Libraries

library(ggplot2)
library(viridis)
Loading required package: viridisLite
library(pheatmap)
library(grid)
library(gridExtra)

Data

Parameters

Directories used:

outdir <- "/mnt/bmh01-rds/UoOxford_David_W/b05055gj/AmplificationTimeR_synthetic_tests/multinomial_sampled_data/final_figures/"
results_dir <- "/mnt/bmh01-rds/UoOxford_David_W/b05055gj/AmplificationTimeR_synthetic_tests/multinomial_sampled_data/"

Experimental parameters:

state_timing_replicates <- 100 # number of replicates for error vs mut number
n_replicates_clocklike <- 100 # number of replicates for error vs clocklike
n_mutations_clocklike_test <- 100 # number of mutations used for clocklike assessment
n_replicates_mismatched <- 100 # number of replicates for timing with different equations
n_mutations_mismatched <- 100 # number of mutations used for timing with different equations
data_type <- "multinomial"

Output figure parameters:

figure_height <- 22.5
figure_width <- 17.8
figure_width_half <- 8.6
resolution <- 350

Multinomial simulated data

# Mutation number
multinomial_mutation_number_and_accuracy <- read.delim(paste0(results_dir,"Error_vs_mutation_number/mutation_number_and_error_rate_100_replicates_multinomial_sampled_data_2024-01-07.txt"), sep = "\t", header = TRUE, row.names = 1)
multinomial_mutation_number_and_number_correct_order <- read.delim(paste0(results_dir,"Error_vs_mutation_number/mutation_number_and_correct_order_100_replicates_multinomial_sampled_data_2024-01-07.txt"), sep = "\t", header = TRUE, row.names = 1)

# Clocklike proportion
multinomial_clocklike_proportions_and_accuracy <- read.delim(paste0(results_dir,"Error_vs_proportion_clocklike/clocklike_proportion_and_error_rate_100_replicates100_mutations_multinomial_sampled_data_2024-01-08.txt"), sep = "\t", header = TRUE, row.names = 1)
multinomial_clocklike_proportions_and_number_correct_order <- read.delim(paste0(results_dir,"Error_vs_proportion_clocklike/clocklike_proportion_and_correct_order_100_replicates100_mutations_multinomial_sampled_data_2024-01-08.txt"), sep = "\t", header = TRUE, row.names = 1)

Multinomial simulated data plots

Mutation Number

Error rate v mutation number

colnames(multinomial_mutation_number_and_accuracy) <- gsub("X","",colnames(multinomial_mutation_number_and_accuracy))
plot_multinomial_mutation_number_and_accuracy <- as.matrix(multinomial_mutation_number_and_accuracy)
rownames(plot_multinomial_mutation_number_and_accuracy) <- rownames(multinomial_mutation_number_and_accuracy)
png(paste0(outdir,"mutation_number_and_error_rate_",
                                                 state_timing_replicates,"_replicates",
                                                 "_","multinomial_data","_",
                                                 Sys.Date(),".png"),
    height = figure_height, width = figure_width, res = resolution, units = "cm")
setHook("grid.newpage", function() pushViewport(viewport(x=1,y=1,width=0.9, height=0.95, name="vp", just=c("right","top"))), action="prepend")
pheatmap(plot_multinomial_mutation_number_and_accuracy, 
        cluster_rows = FALSE, cluster_cols = FALSE,
        # col = viridis(100),
        color = c(viridis(100), viridis(100)[100]),
        breaks = c(0:100,max(plot_multinomial_mutation_number_and_accuracy)),
        main = paste0("Average error rate (%) of timing (n=",state_timing_replicates,") - ","Multinomial Simulated Data"),
        xlab = "Number of mutations simulated",
        ylab = "Copy number state and order",
        border_color = NA,
        scale = "none",
        fontsize_row = 7)
setHook("grid.newpage", NULL, "replace")
grid.text("Number of mutations simulated", y=-0.02, gp=gpar(fontsize=16))
grid.text("Copy number state and order", x=-0.07, rot=90, gp=gpar(fontsize=16))

dev.off()
png 
  3 

Correct orders v mutation number

colnames(multinomial_mutation_number_and_number_correct_order) <- gsub("X","",colnames(multinomial_mutation_number_and_number_correct_order))
plot_multinomial_mutation_number_and_number_correct_order <- as.matrix(multinomial_mutation_number_and_number_correct_order)
rownames(plot_multinomial_mutation_number_and_number_correct_order) <- rownames(multinomial_mutation_number_and_number_correct_order)
png(paste0(outdir,
                                                 "mutation_number_and_correct_order_",
                                                 state_timing_replicates,"_replicates",
                                                 "_","multinomial_Data","_",
                                                 Sys.Date(),".png"),
    height = figure_height, width = figure_width, res = resolution, units = "cm")
setHook("grid.newpage", function() pushViewport(viewport(x=1,y=1,width=0.9, height=0.95, name="vp", just=c("right","top"))), action="prepend")
pheatmap(plot_multinomial_mutation_number_and_number_correct_order, 
        cluster_rows = FALSE, cluster_cols = FALSE,
        col = viridis(100),
        main = paste0("Number of correct timing orders (n=",state_timing_replicates,") - ","Multinomial Simulated Data"),
        border_color = NA,
        scale = "none",
        fontsize_row = 7)
setHook("grid.newpage", NULL, "replace")
grid.text("Number of mutations simulated", y=-0.02, gp=gpar(fontsize=16))
grid.text("Copy number state and order", x=-0.07, rot=90, gp=gpar(fontsize=16))

dev.off()
png 
  3 

Clocklike proportion

Error rate v clocklike proportion

colnames(multinomial_clocklike_proportions_and_accuracy) <- gsub("X","",colnames(multinomial_clocklike_proportions_and_accuracy))
plot_multinomial_clocklike_proportions_and_accuracy <- as.matrix(multinomial_clocklike_proportions_and_accuracy)
rownames(plot_multinomial_clocklike_proportions_and_accuracy) <- rownames(multinomial_clocklike_proportions_and_accuracy)
png(paste0(outdir,
                                                 "clocklike_proportion_and_error_rate_",
                                                 n_replicates_clocklike,"_replicates",
                                                 n_mutations_clocklike_test,"_mutations",
                                                 "_","multinomial_data","_",
                                                 Sys.Date(),".png"),
    height = figure_height, width = figure_width, res = resolution, units = "cm")
setHook("grid.newpage", function() pushViewport(viewport(x=1,y=1,width=0.9, height=0.95, name="vp", just=c("right","top"))), action="prepend")
pheatmap(plot_multinomial_clocklike_proportions_and_accuracy, 
        cluster_rows = FALSE, cluster_cols = FALSE,
        # col = viridis(100),
        color = c(viridis(100), viridis(100)[100]),
        breaks = c(0:100,max(plot_multinomial_clocklike_proportions_and_accuracy)),
        main = paste0("Average error rate (%) of timing (n=",state_timing_replicates,") - ","Multinomial Simulated Data"),
        xlab = "Proportion of clocklike mutations simulated",
        ylab = "Copy number state and order",
        border_color = NA,
        scale = "none",
        fontsize_row = 7)
setHook("grid.newpage", NULL, "replace")
grid.text("Proportion of clocklike mutations simulated", y=-0.02, gp=gpar(fontsize=16))
grid.text("Copy number state and order", x=-0.07, rot=90, gp=gpar(fontsize=16))

dev.off()
png 
  3 

Correct orders v clocklike proportion

colnames(multinomial_clocklike_proportions_and_number_correct_order) <- gsub("X","",colnames(multinomial_clocklike_proportions_and_number_correct_order))
plot_multinomial_clocklike_proportions_and_number_correct_order <- as.matrix(multinomial_clocklike_proportions_and_number_correct_order)
rownames(plot_multinomial_clocklike_proportions_and_number_correct_order) <- rownames(multinomial_clocklike_proportions_and_number_correct_order)
png(paste0(outdir,
                                                 "clocklike_proportion_and_correct_order_",
                                                 n_replicates_clocklike,"_replicates",
                                                 n_mutations_clocklike_test,"_mutations",
                                                 "_","multinomial_data","_",
                                                 Sys.Date(),".png"),
    height = figure_height, width = figure_width, res = resolution, units = "cm")
setHook("grid.newpage", function() pushViewport(viewport(x=1,y=1,width=0.9, height=0.95, name="vp", just=c("right","top"))), action="prepend")
pheatmap(plot_multinomial_clocklike_proportions_and_number_correct_order, 
        cluster_rows = FALSE, cluster_cols = FALSE,
        col = viridis(100),
        main = paste0("Number of correct timing orders (n=",state_timing_replicates,") - ","Multinomial Simulated Data"),
        border_color = NA,
        scale = "none",
        fontsize_row = 7)
setHook("grid.newpage", NULL, "replace")
grid.text("Proportion of clocklike mutations simulated", y=-0.02, gp=gpar(fontsize=16))
grid.text("Copy number state and order", x=-0.07, rot=90, gp=gpar(fontsize=16))

dev.off()
png 
  3 

Combined plot

Plotting two error rateheatmaps together

mut_number_accuracy_heatmap <- pheatmap(plot_multinomial_mutation_number_and_accuracy, 
        cluster_rows = FALSE, cluster_cols = FALSE,
        # col = viridis(100),
        color = c(viridis(100), viridis(100)[100]),
        breaks = c(0:100,max(plot_multinomial_mutation_number_and_accuracy)),
        main = paste0("Average error rate (%) of timing \n(n=",state_timing_replicates,")"),
        xlab = "Number of mutations simulated",
        ylab = "Copy number state and order",
        border_color = NA,
        scale = "none",
        fontsize = 7)

clocklike_accuracy_heatmap <- pheatmap(plot_multinomial_clocklike_proportions_and_accuracy, 
        cluster_rows = FALSE, cluster_cols = FALSE,
        # col = viridis(100),
        color = c(viridis(100), viridis(100)[100]),
        breaks = c(0:100,max(plot_multinomial_clocklike_proportions_and_accuracy)),
        main = paste0("Average error rate (%) of timing \n(n=",state_timing_replicates,")"),
        xlab = "Proportion of clocklike mutations simulated",
        ylab = "Copy number state and order",
        border_color = NA,
        scale = "none",
        fontsize = 7)

png(paste0(outdir,"mutation_number_and_error_rate_",
                                                 state_timing_replicates,"_replicates",
           "clocklike_proportion_and_error_rate_",
                                                 n_replicates_clocklike,"_replicates",
                                                 n_mutations_clocklike_test,"_mutations",
                                                 "_","multinomial_data","_",
                                                 Sys.Date(),".png"),
    height = figure_height, width = figure_width, res = resolution, units = "cm")

setHook("grid.newpage", function() pushViewport(viewport(x=1,y=1,width=0.95, height=0.95, name="vp", just=c("right","top"))), action="prepend")
grid.arrange(grobs = list(mut_number_accuracy_heatmap[[4]],clocklike_accuracy_heatmap[[4]]),
             ncol = 2)
setHook("grid.newpage", NULL, "replace")
grid.text("Number of mutations simulated", y=-0.02, x = 0.22, gp=gpar(fontsize=12))
grid.text("Proportion of clocklike mutations simulated", y=-0.02, x = 0.73, gp=gpar(fontsize=12))
grid.text("Copy number state and order", x=-0.02, rot=90, gp=gpar(fontsize=14))

grid.text("A", x=-0.02, y=0.98, gp=gpar(fontsize=16))
grid.text("B", x=0.47, y=0.98, gp=gpar(fontsize=16))

dev.off()
png 
  2 

Plotting two order heatmaps together

mut_number_order_heatmap <- pheatmap(plot_multinomial_mutation_number_and_number_correct_order, 
        cluster_rows = FALSE, cluster_cols = FALSE,
        col = viridis(100),
        main = paste0("Number of correct timing orders \n(n=",state_timing_replicates,")"),
        border_color = NA,
        scale = "none",
        fontsize = 7)

clocklike_order_heatmap <- pheatmap(plot_multinomial_clocklike_proportions_and_number_correct_order, 
        cluster_rows = FALSE, cluster_cols = FALSE,
        col = viridis(100),
        main = paste0("Number of correct timing orders \n(n=",state_timing_replicates,")"),
        border_color = NA,
        scale = "none",
        fontsize = 7)

png(paste0(outdir,"mutation_number_and_correct_order_",
                                                 state_timing_replicates,"_replicates",
           "clocklike_proportion_and_correct_order_",
                                                 n_replicates_clocklike,"_replicates",
                                                 n_mutations_clocklike_test,"_mutations",
                                                 "_","multinomial_data","_",
                                                 Sys.Date(),".png"),
    height = figure_height, width = figure_width, res = resolution, units = "cm")

setHook("grid.newpage", function() pushViewport(viewport(x=1,y=1,width=0.95, height=0.95, name="vp", just=c("right","top"))), action="prepend")
grid.arrange(grobs = list(mut_number_order_heatmap[[4]],clocklike_order_heatmap[[4]]),
             ncol = 2)
setHook("grid.newpage", NULL, "replace")
grid.text("Number of mutations simulated", y=-0.02, x = 0.22, gp=gpar(fontsize=12))
grid.text("Proportion of clocklike mutations simulated", y=-0.02, x = 0.73, gp=gpar(fontsize=12))
grid.text("Copy number state and order", x=-0.02, rot=90, gp=gpar(fontsize=14))

grid.text("A", x=-0.02, y=0.98, gp=gpar(fontsize=16))
grid.text("B", x=0.47, y=0.98, gp=gpar(fontsize=16))

dev.off()
png 
  2 

Mismatched equation data

Try new plotting approach

4+x

Read in sample data.

cn_4_0_WGG <- read.delim(paste0(results_dir,"applying_right_and_wrong_equations/right_vs_wrong_equations_spearman_correlation_4+0 WGG_100_replicates100_mutations_multinomial_data_2024-01-05.txt"), header = TRUE, sep = "\t")
cn_4_0_GW <- read.delim(paste0(results_dir,"applying_right_and_wrong_equations/right_vs_wrong_equations_spearman_correlation_4+0 GW_100_replicates100_mutations_multinomial_data_2024-01-05.txt"), header = TRUE, sep = "\t")

cn_4_1_WGG <- read.delim(paste0(results_dir,"applying_right_and_wrong_equations/right_vs_wrong_equations_spearman_correlation_4+1 WGG_100_replicates100_mutations_multinomial_data_2024-01-05.txt"), header = TRUE, sep = "\t")
cn_4_1_GW <- read.delim(paste0(results_dir,"applying_right_and_wrong_equations/right_vs_wrong_equations_spearman_correlation_4+1 GW_100_replicates100_mutations_multinomial_data_2024-01-05.txt"), header = TRUE, sep = "\t")

cn_4_2_WGG <- read.delim(paste0(results_dir,"applying_right_and_wrong_equations/right_vs_wrong_equations_spearman_correlation_4+2 WGG_100_replicates100_mutations_multinomial_data_2024-01-05.txt"), header = TRUE, sep = "\t")
cn_4_2_GW <- read.delim(paste0(results_dir,"applying_right_and_wrong_equations/right_vs_wrong_equations_spearman_correlation_4+2 GW_100_replicates100_mutations_multinomial_data_2024-01-05.txt"), header = TRUE, sep = "\t")
cn_4_x <- rbind(cn_4_0_WGG, cn_4_0_GW,
                cn_4_1_WGG, cn_4_1_GW,
                cn_4_2_WGG, cn_4_2_GW)
cn_4_x$Significance <- ifelse(cn_4_x$Spearman_adjusted_p < 0.05, "Significant","Not \nSignificant")
cn_4_x_pearson_plot <- ggplot(cn_4_x, aes(x = True_order, y = Applied_order, fill = Spearman_rho))+
  geom_tile(aes(color=as.factor(Significance), width=0.9, height=0.9), size=0.3)+
  scale_colour_manual(values = c("firebrick","royalblue","grey"), limits = c("Significant","\nNot Significant",NA), name = "Adjusted p")+
  geom_text(aes(label=round(Spearman_rho,digits = 2)), size = 2)+
  facet_grid(rows = vars(Timepoint), cols = vars(CN_state))+
  # scale_fill_gradientn(colors = viridis_pal(option = "magma")(100), limits=c(-1, 1), 
  #                      na.value = "grey")+
  scale_fill_distiller(palette = "RdBu", limits = c(-1,1), name = "Spearman ρ")+
  # scale_fill_viridis(option = "magma")+
  theme_minimal()+
  ylab("Applied timing order")+
  xlab("True simulated timing order")
Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
ℹ Please use `linewidth` instead.
This warning is displayed once every 8 hours.
Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
generated.
cn_4_x_pearson_plot
Warning: Removed 3 rows containing missing values (`geom_text()`).

5+x

Read in sample data.

cn_5_0_WGGG <- read.delim(paste0(results_dir,"applying_right_and_wrong_equations/right_vs_wrong_equations_spearman_correlation_5+0 WGGG_100_replicates100_mutations_multinomial_data_2024-01-05.txt"), header = TRUE, sep = "\t")
cn_5_0_GWG <- read.delim(paste0(results_dir,"applying_right_and_wrong_equations/right_vs_wrong_equations_spearman_correlation_5+0 GWG_100_replicates100_mutations_multinomial_data_2024-01-05.txt"), header = TRUE, sep = "\t")

cn_5_1_WGGG <- read.delim(paste0(results_dir,"applying_right_and_wrong_equations/right_vs_wrong_equations_spearman_correlation_5+1 WGGG_100_replicates100_mutations_multinomial_data_2024-01-05.txt"), header = TRUE, sep = "\t")
cn_5_1_GWG <- read.delim(paste0(results_dir,"applying_right_and_wrong_equations/right_vs_wrong_equations_spearman_correlation_5+1 GWG_100_replicates100_mutations_multinomial_data_2024-01-05.txt"), header = TRUE, sep = "\t")

cn_5_2_WGGG <- read.delim(paste0(results_dir,"applying_right_and_wrong_equations/right_vs_wrong_equations_spearman_correlation_5+2 WGGG_100_replicates100_mutations_multinomial_data_2024-01-05.txt"), header = TRUE, sep = "\t")
cn_5_2_GWG <- read.delim(paste0(results_dir,"applying_right_and_wrong_equations/right_vs_wrong_equations_spearman_correlation_5+2 GWG_100_replicates100_mutations_multinomial_data_2024-01-05.txt"), header = TRUE, sep = "\t")
cn_5_x <- rbind(cn_5_0_WGGG, cn_5_0_GWG,
                cn_5_1_WGGG, cn_5_1_GWG,
                cn_5_2_WGGG, cn_5_2_GWG)
cn_5_x$Significance <- ifelse(cn_5_x$Spearman_adjusted_p < 0.05, "Significant","Not Significant")
cn_5_x_pearson_plot <- ggplot(cn_5_x, aes(x = True_order, y = Applied_order, fill = Spearman_rho))+
  geom_tile(aes(color=as.factor(Significance), width=0.9, height=0.9), size=0.3)+
  scale_colour_manual(values = c("firebrick","royalblue","grey"), limits = c("Significant","Not Significant",NA), name = "Adjusted p")+
  geom_text(aes(label=round(Spearman_rho,digits = 2)), size = 2)+
  facet_grid(rows = vars(Timepoint), cols = vars(CN_state))+
  # scale_fill_gradientn(colors = viridis_pal(option = "magma")(100), limits=c(-1, 1), 
  #                      na.value = "grey")+
  scale_fill_distiller(palette = "RdBu", limits = c(-1,1), name = "Spearman ρ")+
  # scale_fill_viridis(option = "magma")+
  theme_minimal()+
  ylab("Applied timing order")+
  xlab("True simulated timing order")
cn_5_x_pearson_plot
Warning: Removed 3 rows containing missing values (`geom_text()`).

6+x

Read in sample data.

cn_6_0_WGGGG <- read.delim(paste0(results_dir,"applying_right_and_wrong_equations/right_vs_wrong_equations_spearman_correlation_6+0 WGGGG_100_replicates100_mutations_multinomial_data_2024-01-05.txt"), header = TRUE, sep = "\t")
cn_6_0_GWGG <- read.delim(paste0(results_dir,"applying_right_and_wrong_equations/right_vs_wrong_equations_spearman_correlation_6+0 GWGG_100_replicates100_mutations_multinomial_data_2024-01-05.txt"), header = TRUE, sep = "\t")
cn_6_0_GGW <- read.delim(paste0(results_dir,"applying_right_and_wrong_equations/right_vs_wrong_equations_spearman_correlation_6+0 GGW_100_replicates100_mutations_multinomial_data_2024-01-05.txt"), header = TRUE, sep = "\t")

cn_6_1_WGGGG <- read.delim(paste0(results_dir,"applying_right_and_wrong_equations/right_vs_wrong_equations_spearman_correlation_6+1 WGGGG_100_replicates100_mutations_multinomial_data_2024-01-05.txt"), header = TRUE, sep = "\t")
cn_6_1_GWGG <- read.delim(paste0(results_dir,"applying_right_and_wrong_equations/right_vs_wrong_equations_spearman_correlation_6+1 GWGG_100_replicates100_mutations_multinomial_data_2024-01-05.txt"), header = TRUE, sep = "\t")
cn_6_1_GGW <- read.delim(paste0(results_dir,"applying_right_and_wrong_equations/right_vs_wrong_equations_spearman_correlation_6+1 GGW_100_replicates100_mutations_multinomial_data_2024-01-05.txt"), header = TRUE, sep = "\t")

cn_6_2_WGGGG <- read.delim(paste0(results_dir,"applying_right_and_wrong_equations/right_vs_wrong_equations_spearman_correlation_6+2 WGGGG_100_replicates100_mutations_multinomial_data_2024-01-05.txt"), header = TRUE, sep = "\t")
cn_6_2_GWGG <- read.delim(paste0(results_dir,"applying_right_and_wrong_equations/right_vs_wrong_equations_spearman_correlation_6+2 GWGG_100_replicates100_mutations_multinomial_data_2024-01-05.txt"), header = TRUE, sep = "\t")
cn_6_2_GGW <- read.delim(paste0(results_dir,"applying_right_and_wrong_equations/right_vs_wrong_equations_spearman_correlation_6+2 GGW_100_replicates100_mutations_multinomial_data_2024-01-05.txt"), header = TRUE, sep = "\t")
cn_6_x <- rbind(cn_6_0_WGGGG, cn_6_0_GWGG, cn_6_0_GGW,
                cn_6_1_WGGGG, cn_6_1_GWGG, cn_6_1_GGW,
                cn_6_2_WGGGG, cn_6_2_GWGG, cn_6_2_GGW)
cn_6_x$Significance <- ifelse(cn_6_x$Spearman_adjusted_p < 0.05, "Significant","Not Significant")
cn_6_x_pearson_plot <- ggplot(cn_6_x, aes(x = True_order, y = Applied_order, fill = Spearman_rho))+
  geom_tile(aes(color=as.factor(Significance), width=0.9, height=0.9), size=0.3)+
  scale_colour_manual(values = c("firebrick","royalblue","grey"), limits = c("Significant","Not Significant",NA), name = "Adjusted p")+
  geom_text(aes(label=round(Spearman_rho,digits = 2)), size = 2)+
  facet_grid(rows = vars(Timepoint), cols = vars(CN_state))+
  # scale_fill_gradientn(colors = viridis_pal(option = "magma")(100), limits=c(-1, 1), 
  #                      na.value = "grey")+
  scale_fill_distiller(palette = "RdBu", limits = c(-1,1), name = "Spearman ρ")+
  # scale_fill_viridis(option = "magma")+
  theme_minimal()+
  ylab("Applied timing order")+
  xlab("True simulated timing order")
cn_6_x_pearson_plot
Warning: Removed 12 rows containing missing values (`geom_text()`).

7+x

Read in sample data.

cn_7_0_WGGGGG <- read.delim(paste0(results_dir,"applying_right_and_wrong_equations/right_vs_wrong_equations_spearman_correlation_7+0 WGGGGG_100_replicates100_mutations_multinomial_data_2024-01-05.txt"), header = TRUE, sep = "\t")
cn_7_0_GWGGG <- read.delim(paste0(results_dir,"applying_right_and_wrong_equations/right_vs_wrong_equations_spearman_correlation_7+0 GWGGG_100_replicates100_mutations_multinomial_data_2024-01-05.txt"), header = TRUE, sep = "\t")
cn_7_0_GGWG <- read.delim(paste0(results_dir,"applying_right_and_wrong_equations/right_vs_wrong_equations_spearman_correlation_7+0 GGWG_100_replicates100_mutations_multinomial_data_2024-01-05.txt"), header = TRUE, sep = "\t")

cn_7_1_WGGGGG <- read.delim(paste0(results_dir,"applying_right_and_wrong_equations/right_vs_wrong_equations_spearman_correlation_7+1 WGGGGG_100_replicates100_mutations_multinomial_data_2024-01-05.txt"), header = TRUE, sep = "\t")
cn_7_1_GWGGG <- read.delim(paste0(results_dir,"applying_right_and_wrong_equations/right_vs_wrong_equations_spearman_correlation_7+1 GWGGG_100_replicates100_mutations_multinomial_data_2024-01-05.txt"), header = TRUE, sep = "\t")
cn_7_1_GGWG <- read.delim(paste0(results_dir,"applying_right_and_wrong_equations/right_vs_wrong_equations_spearman_correlation_7+1 GGWG_100_replicates100_mutations_multinomial_data_2024-01-05.txt"), header = TRUE, sep = "\t")

cn_7_2_WGGGGG <- read.delim(paste0(results_dir,"applying_right_and_wrong_equations/right_vs_wrong_equations_spearman_correlation_7+2 WGGGGG_100_replicates100_mutations_multinomial_data_2024-01-05.txt"), header = TRUE, sep = "\t")
cn_7_2_GWGGG <- read.delim(paste0(results_dir,"applying_right_and_wrong_equations/right_vs_wrong_equations_spearman_correlation_7+2 GWGGG_100_replicates100_mutations_multinomial_data_2024-01-05.txt"), header = TRUE, sep = "\t")
cn_7_2_GGWG <- read.delim(paste0(results_dir,"applying_right_and_wrong_equations/right_vs_wrong_equations_spearman_correlation_7+2 GGWG_100_replicates100_mutations_multinomial_data_2024-01-05.txt"), header = TRUE, sep = "\t")
cn_7_x <- rbind(cn_7_0_WGGGGG, cn_7_0_GWGGG, cn_7_0_GGWG,
                cn_7_1_WGGGGG, cn_7_1_GWGGG, cn_7_1_GGWG,
                cn_7_2_WGGGGG, cn_7_2_GWGGG, cn_7_2_GGWG)
cn_7_x$Significance <- ifelse(cn_7_x$Spearman_adjusted_p < 0.05, "Significant","Not Significant")
cn_7_x_pearson_plot <- ggplot(cn_7_x, aes(x = True_order, y = Applied_order, fill = Spearman_rho))+
  geom_tile(aes(color=as.factor(Significance), width=0.9, height=0.9), size=0.3)+
  scale_colour_manual(values = c("firebrick","royalblue","grey"), limits = c("Significant","Not Significant",NA), name = "Adjusted p")+
  geom_text(aes(label=round(Spearman_rho,digits = 2)), size = 2)+
  facet_grid(rows = vars(Timepoint), cols = vars(CN_state))+
  # scale_fill_gradientn(colors = viridis_pal(option = "magma")(100), limits=c(-1, 1), 
  #                      na.value = "grey")+
  scale_fill_distiller(palette = "RdBu", limits = c(-1,1), name = "Spearman ρ")+
  # scale_fill_viridis(option = "magma")+
  theme_minimal()+
  ylab("Applied timing order")+
  xlab("True simulated timing order")
cn_7_x_pearson_plot
Warning: Removed 12 rows containing missing values (`geom_text()`).

8+x

Read in sample data.

cn_8_0_WGGGGGG <- read.delim(paste0(results_dir,"applying_right_and_wrong_equations/right_vs_wrong_equations_spearman_correlation_8+0 WGGGGGG_100_replicates100_mutations_multinomial_data_2024-01-05.txt"), header = TRUE, sep = "\t")
cn_8_0_GWGGGG <- read.delim(paste0(results_dir,"applying_right_and_wrong_equations/right_vs_wrong_equations_spearman_correlation_8+0 GWGGGG_100_replicates100_mutations_multinomial_data_2024-01-05.txt"), header = TRUE, sep = "\t")
cn_8_0_GGWGG <- read.delim(paste0(results_dir,"applying_right_and_wrong_equations/right_vs_wrong_equations_spearman_correlation_8+0 GGWGG_100_replicates100_mutations_multinomial_data_2024-01-05.txt"), header = TRUE, sep = "\t")
cn_8_0_GGGW <- read.delim(paste0(results_dir,"applying_right_and_wrong_equations/right_vs_wrong_equations_spearman_correlation_8+0 GGGW_100_replicates100_mutations_multinomial_data_2024-01-05.txt"), header = TRUE, sep = "\t")

cn_8_1_WGGGGGG <- read.delim(paste0(results_dir,"applying_right_and_wrong_equations/right_vs_wrong_equations_spearman_correlation_8+1 WGGGGGG_100_replicates100_mutations_multinomial_data_2024-01-05.txt"), header = TRUE, sep = "\t")
cn_8_1_GWGGGG <- read.delim(paste0(results_dir,"applying_right_and_wrong_equations/right_vs_wrong_equations_spearman_correlation_8+1 GWGGGG_100_replicates100_mutations_multinomial_data_2024-01-05.txt"), header = TRUE, sep = "\t")
cn_8_1_GGWGG <- read.delim(paste0(results_dir,"applying_right_and_wrong_equations/right_vs_wrong_equations_spearman_correlation_8+1 GGWGG_100_replicates100_mutations_multinomial_data_2024-01-05.txt"), header = TRUE, sep = "\t")
cn_8_1_GGGW <- read.delim(paste0(results_dir,"applying_right_and_wrong_equations/right_vs_wrong_equations_spearman_correlation_8+1 GGGW_100_replicates100_mutations_multinomial_data_2024-01-05.txt"), header = TRUE, sep = "\t")

cn_8_2_WGGGGGG <- read.delim(paste0(results_dir,"applying_right_and_wrong_equations/right_vs_wrong_equations_spearman_correlation_8+2 WGGGGGG_100_replicates100_mutations_multinomial_data_2024-01-05.txt"), header = TRUE, sep = "\t")
cn_8_2_GWGGGG <- read.delim(paste0(results_dir,"applying_right_and_wrong_equations/right_vs_wrong_equations_spearman_correlation_8+2 GWGGGG_100_replicates100_mutations_multinomial_data_2024-01-05.txt"), header = TRUE, sep = "\t")
cn_8_2_GGWGG <- read.delim(paste0(results_dir,"applying_right_and_wrong_equations/right_vs_wrong_equations_spearman_correlation_8+2 GGWGG_100_replicates100_mutations_multinomial_data_2024-01-05.txt"), header = TRUE, sep = "\t")
cn_8_2_GGGW <- read.delim(paste0(results_dir,"applying_right_and_wrong_equations/right_vs_wrong_equations_spearman_correlation_8+2 GGGW_100_replicates100_mutations_multinomial_data_2024-01-05.txt"), header = TRUE, sep = "\t")
cn_8_x <- rbind(cn_8_0_WGGGGGG, cn_8_0_GWGGGG, cn_8_0_GGWGG, cn_8_0_GGGW,
                cn_8_1_WGGGGGG, cn_8_1_GWGGGG, cn_8_1_GGWGG, cn_8_1_GGGW,
                cn_8_2_WGGGGGG, cn_8_2_GWGGGG, cn_8_2_GGWGG, cn_8_2_GGGW)
cn_8_x$Significance <- ifelse(cn_8_x$Spearman_adjusted_p < 0.05, "Significant","Not Significant")
cn_8_x_pearson_plot <- ggplot(cn_8_x, aes(x = True_order, y = Applied_order, fill = Spearman_rho))+
  geom_tile(aes(color=as.factor(Significance), width=0.9, height=0.9), size=0.3)+
  scale_colour_manual(values = c("firebrick","royalblue","grey"), limits = c("Significant","Not Significant",NA), name = "Adjusted p")+
  geom_text(aes(label=round(Spearman_rho,digits = 2)), size = 2)+
  facet_grid(rows = vars(Timepoint), cols = vars(CN_state))+
  # scale_fill_gradientn(colors = viridis_pal(option = "magma")(100), limits=c(-1, 1), 
  #                      na.value = "grey")+
  scale_fill_distiller(palette = "RdBu", limits = c(-1,1), name = "Spearman ρ")+
  # scale_fill_viridis(option = "magma")+
  theme_minimal()+
  ylab("Applied timing order")+
  xlab("True simulated timing order")
cn_8_x_pearson_plot
Warning: Removed 30 rows containing missing values (`geom_text()`).

9+x

Read in sample data.

cn_9_0_WGGGGGGG <- read.delim(paste0(results_dir,"applying_right_and_wrong_equations/right_vs_wrong_equations_spearman_correlation_9+0 WGGGGGGG_100_replicates100_mutations_multinomial_data_2024-01-05.txt"), header = TRUE, sep = "\t")
cn_9_0_GWGGGGG <- read.delim(paste0(results_dir,"applying_right_and_wrong_equations/right_vs_wrong_equations_spearman_correlation_9+0 GWGGGGG_100_replicates100_mutations_multinomial_data_2024-01-05.txt"), header = TRUE, sep = "\t")
cn_9_0_GGWGGG <- read.delim(paste0(results_dir,"applying_right_and_wrong_equations/right_vs_wrong_equations_spearman_correlation_9+0 GGWGGG_100_replicates100_mutations_multinomial_data_2024-01-05.txt"), header = TRUE, sep = "\t")
cn_9_0_GGGWG <- read.delim(paste0(results_dir,"applying_right_and_wrong_equations/right_vs_wrong_equations_spearman_correlation_9+0 GGGWG_100_replicates100_mutations_multinomial_data_2024-01-05.txt"), header = TRUE, sep = "\t")

cn_9_1_WGGGGGGG <- read.delim(paste0(results_dir,"applying_right_and_wrong_equations/right_vs_wrong_equations_spearman_correlation_9+1 WGGGGGGG_100_replicates100_mutations_multinomial_data_2024-01-05.txt"), header = TRUE, sep = "\t")
cn_9_1_GWGGGGG <- read.delim(paste0(results_dir,"applying_right_and_wrong_equations/right_vs_wrong_equations_spearman_correlation_9+1 GWGGGGG_100_replicates100_mutations_multinomial_data_2024-01-05.txt"), header = TRUE, sep = "\t")
cn_9_1_GGWGGG <- read.delim(paste0(results_dir,"applying_right_and_wrong_equations/right_vs_wrong_equations_spearman_correlation_9+1 GGWGGG_100_replicates100_mutations_multinomial_data_2024-01-05.txt"), header = TRUE, sep = "\t")
cn_9_1_GGGWG <- read.delim(paste0(results_dir,"applying_right_and_wrong_equations/right_vs_wrong_equations_spearman_correlation_9+1 GGGWG_100_replicates100_mutations_multinomial_data_2024-01-05.txt"), header = TRUE, sep = "\t")

cn_9_2_WGGGGGGG <- read.delim(paste0(results_dir,"applying_right_and_wrong_equations/right_vs_wrong_equations_spearman_correlation_9+2 WGGGGGGG_100_replicates100_mutations_multinomial_data_2024-01-05.txt"), header = TRUE, sep = "\t")
cn_9_2_GWGGGGG <- read.delim(paste0(results_dir,"applying_right_and_wrong_equations/right_vs_wrong_equations_spearman_correlation_9+2 GWGGGGG_100_replicates100_mutations_multinomial_data_2024-01-05.txt"), header = TRUE, sep = "\t")
cn_9_2_GGWGGG <- read.delim(paste0(results_dir,"applying_right_and_wrong_equations/right_vs_wrong_equations_spearman_correlation_9+2 GGWGGG_100_replicates100_mutations_multinomial_data_2024-01-05.txt"), header = TRUE, sep = "\t")
cn_9_2_GGGWG <- read.delim(paste0(results_dir,"applying_right_and_wrong_equations/right_vs_wrong_equations_spearman_correlation_9+2 GGGWG_100_replicates100_mutations_multinomial_data_2024-01-05.txt"), header = TRUE, sep = "\t")
cn_9_x <- rbind(cn_9_0_WGGGGGGG, cn_9_0_GWGGGGG, cn_9_0_GGWGGG, cn_9_0_GGGWG,
                cn_9_1_WGGGGGGG, cn_9_1_GWGGGGG, cn_9_1_GGWGGG, cn_9_1_GGGWG,
                cn_9_2_WGGGGGGG, cn_9_2_GWGGGGG, cn_9_2_GGWGGG, cn_9_2_GGGWG)
cn_9_x$Significance <- ifelse(cn_9_x$Spearman_adjusted_p < 0.05, "Significant","Not Significant")
cn_9_x_pearson_plot <- ggplot(cn_9_x, aes(x = True_order, y = Applied_order, fill = Spearman_rho))+
  geom_tile(aes(color=as.factor(Significance), width=0.9, height=0.9), size=0.3)+
  scale_colour_manual(values = c("firebrick","royalblue","grey"), limits = c("Significant","Not Significant",NA), name = "Adjusted p")+
  geom_text(aes(label=round(Spearman_rho,digits = 2)), size = 2)+
  facet_grid(rows = vars(Timepoint), cols = vars(CN_state))+
  # scale_fill_gradientn(colors = viridis_pal(option = "magma")(100), limits=c(-1, 1), 
  #                      na.value = "grey")+
  scale_fill_distiller(palette = "RdBu", limits = c(-1,1), name = "Spearman ρ")+
  # scale_fill_viridis(option = "magma")+
  theme_minimal()+
  ylab("Applied timing order")+
  xlab("True simulated timing order")
cn_9_x_pearson_plot
Warning: Removed 30 rows containing missing values (`geom_text()`).

10+x

Read in sample data.

cn_10_0_WGGGGGGGG <- read.delim(paste0(results_dir,"applying_right_and_wrong_equations/right_vs_wrong_equations_spearman_correlation_10+0 WGGGGGGGG_100_replicates100_mutations_multinomial_data_2024-01-05.txt"), header = TRUE, sep = "\t")
cn_10_0_GWGGGGGG <- read.delim(paste0(results_dir,"applying_right_and_wrong_equations/right_vs_wrong_equations_spearman_correlation_10+0 GWGGGGGG_100_replicates100_mutations_multinomial_data_2024-01-05.txt"), header = TRUE, sep = "\t")
cn_10_0_GGWGGGG <- read.delim(paste0(results_dir,"applying_right_and_wrong_equations/right_vs_wrong_equations_spearman_correlation_10+0 GGWGGGG_100_replicates100_mutations_multinomial_data_2024-01-05.txt"), header = TRUE, sep = "\t")
cn_10_0_GGGWGG <- read.delim(paste0(results_dir,"applying_right_and_wrong_equations/right_vs_wrong_equations_spearman_correlation_10+0 GGGWGG_100_replicates100_mutations_multinomial_data_2024-01-05.txt"), header = TRUE, sep = "\t")
cn_10_0_GGGGW <- read.delim(paste0(results_dir,"applying_right_and_wrong_equations/right_vs_wrong_equations_spearman_correlation_10+0 GGGGW_100_replicates100_mutations_multinomial_data_2024-01-05.txt"), header = TRUE, sep = "\t")

cn_10_1_WGGGGGGGG <- read.delim(paste0(results_dir,"applying_right_and_wrong_equations/right_vs_wrong_equations_spearman_correlation_10+1 WGGGGGGGG_100_replicates100_mutations_multinomial_data_2024-01-05.txt"), header = TRUE, sep = "\t")
cn_10_1_GWGGGGGG <- read.delim(paste0(results_dir,"applying_right_and_wrong_equations/right_vs_wrong_equations_spearman_correlation_10+1 GWGGGGGG_100_replicates100_mutations_multinomial_data_2024-01-05.txt"), header = TRUE, sep = "\t")
cn_10_1_GGWGGGG <- read.delim(paste0(results_dir,"applying_right_and_wrong_equations/right_vs_wrong_equations_spearman_correlation_10+1 GGWGGGG_100_replicates100_mutations_multinomial_data_2024-01-05.txt"), header = TRUE, sep = "\t")
cn_10_1_GGGWGG <- read.delim(paste0(results_dir,"applying_right_and_wrong_equations/right_vs_wrong_equations_spearman_correlation_10+1 GGGWGG_100_replicates100_mutations_multinomial_data_2024-01-05.txt"), header = TRUE, sep = "\t")
cn_10_1_GGGGW <- read.delim(paste0(results_dir,"applying_right_and_wrong_equations/right_vs_wrong_equations_spearman_correlation_10+1 GGGGW_100_replicates100_mutations_multinomial_data_2024-01-05.txt"), header = TRUE, sep = "\t")

cn_10_2_WGGGGGGGG <- read.delim(paste0(results_dir,"applying_right_and_wrong_equations/right_vs_wrong_equations_spearman_correlation_10+2 WGGGGGGGG_100_replicates100_mutations_multinomial_data_2024-01-05.txt"), header = TRUE, sep = "\t")
cn_10_2_GWGGGGGG <- read.delim(paste0(results_dir,"applying_right_and_wrong_equations/right_vs_wrong_equations_spearman_correlation_10+2 GWGGGGGG_100_replicates100_mutations_multinomial_data_2024-01-05.txt"), header = TRUE, sep = "\t")
cn_10_2_GGWGGGG <- read.delim(paste0(results_dir,"applying_right_and_wrong_equations/right_vs_wrong_equations_spearman_correlation_10+2 GGWGGGG_100_replicates100_mutations_multinomial_data_2024-01-05.txt"), header = TRUE, sep = "\t")
cn_10_2_GGGWGG <- read.delim(paste0(results_dir,"applying_right_and_wrong_equations/right_vs_wrong_equations_spearman_correlation_10+2 GGGWGG_100_replicates100_mutations_multinomial_data_2024-01-05.txt"), header = TRUE, sep = "\t")
cn_10_2_GGGGW <- read.delim(paste0(results_dir,"applying_right_and_wrong_equations/right_vs_wrong_equations_spearman_correlation_10+2 GGGGW_100_replicates100_mutations_multinomial_data_2024-01-05.txt"), header = TRUE, sep = "\t")
cn_10_x <- rbind(cn_10_0_WGGGGGGGG, cn_10_0_GWGGGGGG, cn_10_0_GGWGGGG, cn_10_0_GGGWGG, cn_10_0_GGGGW,
                 cn_10_1_WGGGGGGGG, cn_10_1_GWGGGGGG, cn_10_1_GGWGGGG, cn_10_1_GGGWGG, cn_10_1_GGGGW,
                 cn_10_2_WGGGGGGGG, cn_10_2_GWGGGGGG, cn_10_2_GGWGGGG, cn_10_2_GGGWGG, cn_10_2_GGGGW)
cn_10_x$Significance <- ifelse(cn_10_x$Spearman_adjusted_p < 0.05, "Significant","Not Significant")
cn_10_x_pearson_plot <- ggplot(cn_10_x, aes(x = True_order, y = Applied_order, fill = Spearman_rho))+
  geom_tile(aes(color=as.factor(Significance), width=0.9, height=0.9), size=0.3)+
  scale_colour_manual(values = c("firebrick","royalblue","grey"), limits = c("Significant","Not Significant",NA), name = "Adjusted p")+
  geom_text(aes(label=round(Spearman_rho,digits = 2)), size = 2)+
  facet_grid(rows = vars(Timepoint), cols = vars(CN_state))+
  # scale_fill_gradientn(colors = viridis_pal(option = "magma")(100), limits=c(-1, 1), 
  #                      na.value = "grey")+
  scale_fill_distiller(palette = "RdBu", limits = c(-1,1), name = "Spearman ρ")+
  # scale_fill_viridis(option = "magma")+
  theme_minimal()+
  ylab("Applied timing order")+
  xlab("True simulated timing order")
cn_10_x_pearson_plot
Warning: Removed 60 rows containing missing values (`geom_text()`).

Combined plot

png(paste0(outdir,"pearson_and_mix_match_equations_4_9_",
                                                 n_replicates_mismatched,"_replicates",
                                                 n_mutations_mismatched,"_mutations",
                                                 "_","multinomial_data","_",
                                                 Sys.Date(),".png"),
    height = figure_height, width = figure_width, units = "cm",
    res = 350)

grid.arrange(cn_4_x_pearson_plot+theme(axis.title = element_blank(),axis.text = element_text(size = 6), plot.margin = unit(c(0,0,0,0.2), "cm"), legend.position = "left", strip.text = element_text(size = 8), legend.box.spacing = unit(0.05, "cm"), legend.key.width = unit(0.3,"cm"), legend.text = element_text(size = 6), legend.title = element_text(size = 6), legend.box = "horizontal", legend.spacing = unit(0,"cm")), 
             cn_5_x_pearson_plot+theme(axis.title = element_blank(),axis.text = element_text(size = 6), plot.margin = unit(c(0,0,0,0), "cm"), legend.position = "none", strip.text = element_text(size = 8)),
             cn_6_x_pearson_plot+theme(axis.title = element_blank(),axis.text = element_text(size = 6), plot.margin = unit(c(0,0,0,0), "cm"), legend.position = "none", strip.text = element_text(size = 8), axis.text.x = element_text(angle = -20)), 
             cn_7_x_pearson_plot+theme(axis.title = element_blank(),axis.text = element_text(size = 6), plot.margin = unit(c(0,0,0,0), "cm"), legend.position = "none", strip.text = element_text(size = 8), axis.text.x = element_text(angle = -20)),
             cn_8_x_pearson_plot+theme(axis.title = element_blank(),axis.text = element_text(size = 6), plot.margin = unit(c(0,0,0,0), "cm"), legend.position = "none", strip.text = element_text(size = 8), axis.text.x = element_text(angle = -25)), 
             cn_9_x_pearson_plot+theme(axis.title = element_blank(),axis.text = element_text(size = 6), plot.margin = unit(c(0,0,0,0), "cm"), legend.position = "none", strip.text = element_text(size = 8), axis.text.x = element_text(angle = -25)),
             # cn_10_x_pearson_plot+theme(axis.title = element_blank(),axis.text = element_text(size = 4), plot.margin = unit(c(0,0,0,0), "cm")),
             ncol = 2, nrow = 3,
             left = "Applied timing order", bottom = "True simulated timing order",
             layout_matrix = rbind(c(1,2),
                                   c(3,4),
                                   c(5,6)
                                   # c(7,7)
                                   ),
             heights = c(3,5,9), padding = unit(0.5, "cm"))
Warning: Removed 3 rows containing missing values (`geom_text()`).
Removed 3 rows containing missing values (`geom_text()`).
Warning: Removed 12 rows containing missing values (`geom_text()`).
Removed 12 rows containing missing values (`geom_text()`).
Warning: Removed 30 rows containing missing values (`geom_text()`).
Removed 30 rows containing missing values (`geom_text()`).
grid.text("A", x=0.05, y=0.98, gp=gpar(fontsize=16))
grid.text("B", x=0.50, y=0.98, gp=gpar(fontsize=16))
grid.text("C", x=0.05, y=0.82, gp=gpar(fontsize=16))
grid.text("D", x=0.50, y=0.82, gp=gpar(fontsize=16))
grid.text("E", x=0.05, y=0.54, gp=gpar(fontsize=16))
grid.text("F", x=0.50, y=0.54, gp=gpar(fontsize=16))

dev.off()
png 
  2 
png(paste0(outdir,"pearson_and_mix_match_equations_10_X_",
                                                 n_replicates_mismatched,"_replicates",
                                                 n_mutations_mismatched,"_mutations",
                                                 "_","multinomial_data","_",
                                                 Sys.Date(),".png"),
    height = 16, width = figure_width, units = "cm",
    res = 350)
cn_10_x_pearson_plot+
  theme(axis.text = element_text(size = 8), 
        axis.text.x = element_text(angle = -20, hjust = -0.01))
Warning: Removed 60 rows containing missing values (`geom_text()`).
dev.off()
png 
  2 

Session info

sessionInfo()
R version 4.2.2 (2022-10-31)
Platform: x86_64-pc-linux-gnu (64-bit)
Running under: CentOS Linux 7 (Core)

Matrix products: default
BLAS:   /opt/apps/apps/gcc/R/4.2.2/lib64/R/lib/libRblas.so
LAPACK: /opt/apps/apps/gcc/R/4.2.2/lib64/R/lib/libRlapack.so

locale:
 [1] LC_CTYPE=en_GB.UTF-8       LC_NUMERIC=C              
 [3] LC_TIME=en_GB.UTF-8        LC_COLLATE=en_GB.UTF-8    
 [5] LC_MONETARY=en_GB.UTF-8    LC_MESSAGES=en_GB.UTF-8   
 [7] LC_PAPER=en_GB.UTF-8       LC_NAME=C                 
 [9] LC_ADDRESS=C               LC_TELEPHONE=C            
[11] LC_MEASUREMENT=en_GB.UTF-8 LC_IDENTIFICATION=C       

attached base packages:
[1] grid      stats     graphics  grDevices utils     datasets  methods  
[8] base     

other attached packages:
[1] gridExtra_2.3     pheatmap_1.0.12   viridis_0.6.4     viridisLite_0.4.2
[5] ggplot2_3.4.4    

loaded via a namespace (and not attached):
 [1] RColorBrewer_1.1-3 bslib_0.4.1        compiler_4.2.2     pillar_1.9.0      
 [5] jquerylib_0.1.4    tools_4.2.2        digest_0.6.33      jsonlite_1.8.7    
 [9] evaluate_0.22      lifecycle_1.0.3    tibble_3.2.1       gtable_0.3.4      
[13] pkgconfig_2.0.3    rlang_1.1.1        cli_3.6.1          rstudioapi_0.15.0 
[17] yaml_2.3.7         xfun_0.40          fastmap_1.1.0      withr_2.5.1       
[21] dplyr_1.1.3        knitr_1.44         generics_0.1.3     vctrs_0.6.4       
[25] sass_0.4.4         tidyselect_1.2.0   glue_1.6.2         R6_2.5.1          
[29] fansi_1.0.5        rmarkdown_2.25     farver_2.1.1       magrittr_2.0.3    
[33] scales_1.2.1       htmltools_0.5.3    colorspace_2.1-0   labeling_0.4.3    
[37] utf8_1.2.4         munsell_0.5.0      cachem_1.0.6       crayon_1.5.2      

Save session info

writeLines(capture.output(sessionInfo()), paste0(outdir,data_type,"_plotting_simulation_sessionInfo_",Sys.Date(),".txt"))
LS0tCnRpdGxlOiAiUGxvdHRpbmcgb3V0cHV0IG9mIHNpbXVsYXRpb25zIHJ1biBvbiBDU0YzIG9uIDA1LTA4LjAxLjI0IgphdXRob3I6ICJNYXJpYSBKYWtvYnNkb3R0aXIiCmRhdGU6ICJgciBmb3JtYXQoU3lzLnRpbWUoKSwgJyVkICVCLCAlWScpYCIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKIyBMaWJyYXJpZXMKYGBge3J9CmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeSh2aXJpZGlzKQpsaWJyYXJ5KHBoZWF0bWFwKQpsaWJyYXJ5KGdyaWQpCmxpYnJhcnkoZ3JpZEV4dHJhKQpgYGAKCiMgRGF0YQojIyBQYXJhbWV0ZXJzCkRpcmVjdG9yaWVzIHVzZWQ6CmBgYHtyfQpvdXRkaXIgPC0gIi9tbnQvYm1oMDEtcmRzL1VvT3hmb3JkX0RhdmlkX1cvYjA1MDU1Z2ovQW1wbGlmaWNhdGlvblRpbWVSX3N5bnRoZXRpY190ZXN0cy9tdWx0aW5vbWlhbF9zYW1wbGVkX2RhdGEvZmluYWxfZmlndXJlcy8iCnJlc3VsdHNfZGlyIDwtICIvbW50L2JtaDAxLXJkcy9Vb094Zm9yZF9EYXZpZF9XL2IwNTA1NWdqL0FtcGxpZmljYXRpb25UaW1lUl9zeW50aGV0aWNfdGVzdHMvbXVsdGlub21pYWxfc2FtcGxlZF9kYXRhLyIKYGBgCgpFeHBlcmltZW50YWwgcGFyYW1ldGVyczoKYGBge3J9CnN0YXRlX3RpbWluZ19yZXBsaWNhdGVzIDwtIDEwMCAjIG51bWJlciBvZiByZXBsaWNhdGVzIGZvciBlcnJvciB2cyBtdXQgbnVtYmVyCm5fcmVwbGljYXRlc19jbG9ja2xpa2UgPC0gMTAwICMgbnVtYmVyIG9mIHJlcGxpY2F0ZXMgZm9yIGVycm9yIHZzIGNsb2NrbGlrZQpuX211dGF0aW9uc19jbG9ja2xpa2VfdGVzdCA8LSAxMDAgIyBudW1iZXIgb2YgbXV0YXRpb25zIHVzZWQgZm9yIGNsb2NrbGlrZSBhc3Nlc3NtZW50Cm5fcmVwbGljYXRlc19taXNtYXRjaGVkIDwtIDEwMCAjIG51bWJlciBvZiByZXBsaWNhdGVzIGZvciB0aW1pbmcgd2l0aCBkaWZmZXJlbnQgZXF1YXRpb25zCm5fbXV0YXRpb25zX21pc21hdGNoZWQgPC0gMTAwICMgbnVtYmVyIG9mIG11dGF0aW9ucyB1c2VkIGZvciB0aW1pbmcgd2l0aCBkaWZmZXJlbnQgZXF1YXRpb25zCmRhdGFfdHlwZSA8LSAibXVsdGlub21pYWwiCmBgYAoKT3V0cHV0IGZpZ3VyZSBwYXJhbWV0ZXJzOgpgYGB7cn0KZmlndXJlX2hlaWdodCA8LSAyMi41CmZpZ3VyZV93aWR0aCA8LSAxNy44CmZpZ3VyZV93aWR0aF9oYWxmIDwtIDguNgpyZXNvbHV0aW9uIDwtIDM1MApgYGAKCiMjIE11bHRpbm9taWFsIHNpbXVsYXRlZCBkYXRhCmBgYHtyfQojIE11dGF0aW9uIG51bWJlcgptdWx0aW5vbWlhbF9tdXRhdGlvbl9udW1iZXJfYW5kX2FjY3VyYWN5IDwtIHJlYWQuZGVsaW0ocGFzdGUwKHJlc3VsdHNfZGlyLCJFcnJvcl92c19tdXRhdGlvbl9udW1iZXIvbXV0YXRpb25fbnVtYmVyX2FuZF9lcnJvcl9yYXRlXzEwMF9yZXBsaWNhdGVzX211bHRpbm9taWFsX3NhbXBsZWRfZGF0YV8yMDI0LTAxLTA3LnR4dCIpLCBzZXAgPSAiXHQiLCBoZWFkZXIgPSBUUlVFLCByb3cubmFtZXMgPSAxKQptdWx0aW5vbWlhbF9tdXRhdGlvbl9udW1iZXJfYW5kX251bWJlcl9jb3JyZWN0X29yZGVyIDwtIHJlYWQuZGVsaW0ocGFzdGUwKHJlc3VsdHNfZGlyLCJFcnJvcl92c19tdXRhdGlvbl9udW1iZXIvbXV0YXRpb25fbnVtYmVyX2FuZF9jb3JyZWN0X29yZGVyXzEwMF9yZXBsaWNhdGVzX211bHRpbm9taWFsX3NhbXBsZWRfZGF0YV8yMDI0LTAxLTA3LnR4dCIpLCBzZXAgPSAiXHQiLCBoZWFkZXIgPSBUUlVFLCByb3cubmFtZXMgPSAxKQoKIyBDbG9ja2xpa2UgcHJvcG9ydGlvbgptdWx0aW5vbWlhbF9jbG9ja2xpa2VfcHJvcG9ydGlvbnNfYW5kX2FjY3VyYWN5IDwtIHJlYWQuZGVsaW0ocGFzdGUwKHJlc3VsdHNfZGlyLCJFcnJvcl92c19wcm9wb3J0aW9uX2Nsb2NrbGlrZS9jbG9ja2xpa2VfcHJvcG9ydGlvbl9hbmRfZXJyb3JfcmF0ZV8xMDBfcmVwbGljYXRlczEwMF9tdXRhdGlvbnNfbXVsdGlub21pYWxfc2FtcGxlZF9kYXRhXzIwMjQtMDEtMDgudHh0IiksIHNlcCA9ICJcdCIsIGhlYWRlciA9IFRSVUUsIHJvdy5uYW1lcyA9IDEpCm11bHRpbm9taWFsX2Nsb2NrbGlrZV9wcm9wb3J0aW9uc19hbmRfbnVtYmVyX2NvcnJlY3Rfb3JkZXIgPC0gcmVhZC5kZWxpbShwYXN0ZTAocmVzdWx0c19kaXIsIkVycm9yX3ZzX3Byb3BvcnRpb25fY2xvY2tsaWtlL2Nsb2NrbGlrZV9wcm9wb3J0aW9uX2FuZF9jb3JyZWN0X29yZGVyXzEwMF9yZXBsaWNhdGVzMTAwX211dGF0aW9uc19tdWx0aW5vbWlhbF9zYW1wbGVkX2RhdGFfMjAyNC0wMS0wOC50eHQiKSwgc2VwID0gIlx0IiwgaGVhZGVyID0gVFJVRSwgcm93Lm5hbWVzID0gMSkKYGBgCgojIE11bHRpbm9taWFsIHNpbXVsYXRlZCBkYXRhIHBsb3RzCiMjIE11dGF0aW9uIE51bWJlcgojIyMgRXJyb3IgcmF0ZSB2IG11dGF0aW9uIG51bWJlcgpgYGB7cn0KY29sbmFtZXMobXVsdGlub21pYWxfbXV0YXRpb25fbnVtYmVyX2FuZF9hY2N1cmFjeSkgPC0gZ3N1YigiWCIsIiIsY29sbmFtZXMobXVsdGlub21pYWxfbXV0YXRpb25fbnVtYmVyX2FuZF9hY2N1cmFjeSkpCnBsb3RfbXVsdGlub21pYWxfbXV0YXRpb25fbnVtYmVyX2FuZF9hY2N1cmFjeSA8LSBhcy5tYXRyaXgobXVsdGlub21pYWxfbXV0YXRpb25fbnVtYmVyX2FuZF9hY2N1cmFjeSkKcm93bmFtZXMocGxvdF9tdWx0aW5vbWlhbF9tdXRhdGlvbl9udW1iZXJfYW5kX2FjY3VyYWN5KSA8LSByb3duYW1lcyhtdWx0aW5vbWlhbF9tdXRhdGlvbl9udW1iZXJfYW5kX2FjY3VyYWN5KQpgYGAKYGBge3J9CnBuZyhwYXN0ZTAob3V0ZGlyLCJtdXRhdGlvbl9udW1iZXJfYW5kX2Vycm9yX3JhdGVfIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXRlX3RpbWluZ19yZXBsaWNhdGVzLCJfcmVwbGljYXRlcyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiXyIsIm11bHRpbm9taWFsX2RhdGEiLCJfIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN5cy5EYXRlKCksIi5wbmciKSwKICAgIGhlaWdodCA9IGZpZ3VyZV9oZWlnaHQsIHdpZHRoID0gZmlndXJlX3dpZHRoLCByZXMgPSByZXNvbHV0aW9uLCB1bml0cyA9ICJjbSIpCnNldEhvb2soImdyaWQubmV3cGFnZSIsIGZ1bmN0aW9uKCkgcHVzaFZpZXdwb3J0KHZpZXdwb3J0KHg9MSx5PTEsd2lkdGg9MC45LCBoZWlnaHQ9MC45NSwgbmFtZT0idnAiLCBqdXN0PWMoInJpZ2h0IiwidG9wIikpKSwgYWN0aW9uPSJwcmVwZW5kIikKcGhlYXRtYXAocGxvdF9tdWx0aW5vbWlhbF9tdXRhdGlvbl9udW1iZXJfYW5kX2FjY3VyYWN5LCAKICAgICAgICBjbHVzdGVyX3Jvd3MgPSBGQUxTRSwgY2x1c3Rlcl9jb2xzID0gRkFMU0UsCiAgICAgICAgIyBjb2wgPSB2aXJpZGlzKDEwMCksCiAgICAgICAgY29sb3IgPSBjKHZpcmlkaXMoMTAwKSwgdmlyaWRpcygxMDApWzEwMF0pLAogICAgICAgIGJyZWFrcyA9IGMoMDoxMDAsbWF4KHBsb3RfbXVsdGlub21pYWxfbXV0YXRpb25fbnVtYmVyX2FuZF9hY2N1cmFjeSkpLAogICAgICAgIG1haW4gPSBwYXN0ZTAoIkF2ZXJhZ2UgZXJyb3IgcmF0ZSAoJSkgb2YgdGltaW5nIChuPSIsc3RhdGVfdGltaW5nX3JlcGxpY2F0ZXMsIikgLSAiLCJNdWx0aW5vbWlhbCBTaW11bGF0ZWQgRGF0YSIpLAogICAgICAgIHhsYWIgPSAiTnVtYmVyIG9mIG11dGF0aW9ucyBzaW11bGF0ZWQiLAogICAgICAgIHlsYWIgPSAiQ29weSBudW1iZXIgc3RhdGUgYW5kIG9yZGVyIiwKICAgICAgICBib3JkZXJfY29sb3IgPSBOQSwKICAgICAgICBzY2FsZSA9ICJub25lIiwKICAgICAgICBmb250c2l6ZV9yb3cgPSA3KQpzZXRIb29rKCJncmlkLm5ld3BhZ2UiLCBOVUxMLCAicmVwbGFjZSIpCmdyaWQudGV4dCgiTnVtYmVyIG9mIG11dGF0aW9ucyBzaW11bGF0ZWQiLCB5PS0wLjAyLCBncD1ncGFyKGZvbnRzaXplPTE2KSkKZ3JpZC50ZXh0KCJDb3B5IG51bWJlciBzdGF0ZSBhbmQgb3JkZXIiLCB4PS0wLjA3LCByb3Q9OTAsIGdwPWdwYXIoZm9udHNpemU9MTYpKQpkZXYub2ZmKCkKYGBgCgojIyMgQ29ycmVjdCBvcmRlcnMgdiBtdXRhdGlvbiBudW1iZXIKYGBge3IgZmlnLmhlaWdodD0xMH0KY29sbmFtZXMobXVsdGlub21pYWxfbXV0YXRpb25fbnVtYmVyX2FuZF9udW1iZXJfY29ycmVjdF9vcmRlcikgPC0gZ3N1YigiWCIsIiIsY29sbmFtZXMobXVsdGlub21pYWxfbXV0YXRpb25fbnVtYmVyX2FuZF9udW1iZXJfY29ycmVjdF9vcmRlcikpCnBsb3RfbXVsdGlub21pYWxfbXV0YXRpb25fbnVtYmVyX2FuZF9udW1iZXJfY29ycmVjdF9vcmRlciA8LSBhcy5tYXRyaXgobXVsdGlub21pYWxfbXV0YXRpb25fbnVtYmVyX2FuZF9udW1iZXJfY29ycmVjdF9vcmRlcikKcm93bmFtZXMocGxvdF9tdWx0aW5vbWlhbF9tdXRhdGlvbl9udW1iZXJfYW5kX251bWJlcl9jb3JyZWN0X29yZGVyKSA8LSByb3duYW1lcyhtdWx0aW5vbWlhbF9tdXRhdGlvbl9udW1iZXJfYW5kX251bWJlcl9jb3JyZWN0X29yZGVyKQpgYGAKYGBge3IgZmlnLmhlaWdodD0xMn0KcG5nKHBhc3RlMChvdXRkaXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAibXV0YXRpb25fbnVtYmVyX2FuZF9jb3JyZWN0X29yZGVyXyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0ZV90aW1pbmdfcmVwbGljYXRlcywiX3JlcGxpY2F0ZXMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIl8iLCJtdWx0aW5vbWlhbF9EYXRhIiwiXyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTeXMuRGF0ZSgpLCIucG5nIiksCiAgICBoZWlnaHQgPSBmaWd1cmVfaGVpZ2h0LCB3aWR0aCA9IGZpZ3VyZV93aWR0aCwgcmVzID0gcmVzb2x1dGlvbiwgdW5pdHMgPSAiY20iKQpzZXRIb29rKCJncmlkLm5ld3BhZ2UiLCBmdW5jdGlvbigpIHB1c2hWaWV3cG9ydCh2aWV3cG9ydCh4PTEseT0xLHdpZHRoPTAuOSwgaGVpZ2h0PTAuOTUsIG5hbWU9InZwIiwganVzdD1jKCJyaWdodCIsInRvcCIpKSksIGFjdGlvbj0icHJlcGVuZCIpCnBoZWF0bWFwKHBsb3RfbXVsdGlub21pYWxfbXV0YXRpb25fbnVtYmVyX2FuZF9udW1iZXJfY29ycmVjdF9vcmRlciwgCiAgICAgICAgY2x1c3Rlcl9yb3dzID0gRkFMU0UsIGNsdXN0ZXJfY29scyA9IEZBTFNFLAogICAgICAgIGNvbCA9IHZpcmlkaXMoMTAwKSwKICAgICAgICBtYWluID0gcGFzdGUwKCJOdW1iZXIgb2YgY29ycmVjdCB0aW1pbmcgb3JkZXJzIChuPSIsc3RhdGVfdGltaW5nX3JlcGxpY2F0ZXMsIikgLSAiLCJNdWx0aW5vbWlhbCBTaW11bGF0ZWQgRGF0YSIpLAogICAgICAgIGJvcmRlcl9jb2xvciA9IE5BLAogICAgICAgIHNjYWxlID0gIm5vbmUiLAogICAgICAgIGZvbnRzaXplX3JvdyA9IDcpCnNldEhvb2soImdyaWQubmV3cGFnZSIsIE5VTEwsICJyZXBsYWNlIikKZ3JpZC50ZXh0KCJOdW1iZXIgb2YgbXV0YXRpb25zIHNpbXVsYXRlZCIsIHk9LTAuMDIsIGdwPWdwYXIoZm9udHNpemU9MTYpKQpncmlkLnRleHQoIkNvcHkgbnVtYmVyIHN0YXRlIGFuZCBvcmRlciIsIHg9LTAuMDcsIHJvdD05MCwgZ3A9Z3Bhcihmb250c2l6ZT0xNikpCmRldi5vZmYoKQpgYGAKCgojIyBDbG9ja2xpa2UgcHJvcG9ydGlvbgojIyMgRXJyb3IgcmF0ZSB2IGNsb2NrbGlrZSBwcm9wb3J0aW9uCmBgYHtyfQpjb2xuYW1lcyhtdWx0aW5vbWlhbF9jbG9ja2xpa2VfcHJvcG9ydGlvbnNfYW5kX2FjY3VyYWN5KSA8LSBnc3ViKCJYIiwiIixjb2xuYW1lcyhtdWx0aW5vbWlhbF9jbG9ja2xpa2VfcHJvcG9ydGlvbnNfYW5kX2FjY3VyYWN5KSkKcGxvdF9tdWx0aW5vbWlhbF9jbG9ja2xpa2VfcHJvcG9ydGlvbnNfYW5kX2FjY3VyYWN5IDwtIGFzLm1hdHJpeChtdWx0aW5vbWlhbF9jbG9ja2xpa2VfcHJvcG9ydGlvbnNfYW5kX2FjY3VyYWN5KQpyb3duYW1lcyhwbG90X211bHRpbm9taWFsX2Nsb2NrbGlrZV9wcm9wb3J0aW9uc19hbmRfYWNjdXJhY3kpIDwtIHJvd25hbWVzKG11bHRpbm9taWFsX2Nsb2NrbGlrZV9wcm9wb3J0aW9uc19hbmRfYWNjdXJhY3kpCmBgYApgYGB7cn0KcG5nKHBhc3RlMChvdXRkaXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiY2xvY2tsaWtlX3Byb3BvcnRpb25fYW5kX2Vycm9yX3JhdGVfIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5fcmVwbGljYXRlc19jbG9ja2xpa2UsIl9yZXBsaWNhdGVzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5fbXV0YXRpb25zX2Nsb2NrbGlrZV90ZXN0LCJfbXV0YXRpb25zIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJfIiwibXVsdGlub21pYWxfZGF0YSIsIl8iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3lzLkRhdGUoKSwiLnBuZyIpLAogICAgaGVpZ2h0ID0gZmlndXJlX2hlaWdodCwgd2lkdGggPSBmaWd1cmVfd2lkdGgsIHJlcyA9IHJlc29sdXRpb24sIHVuaXRzID0gImNtIikKc2V0SG9vaygiZ3JpZC5uZXdwYWdlIiwgZnVuY3Rpb24oKSBwdXNoVmlld3BvcnQodmlld3BvcnQoeD0xLHk9MSx3aWR0aD0wLjksIGhlaWdodD0wLjk1LCBuYW1lPSJ2cCIsIGp1c3Q9YygicmlnaHQiLCJ0b3AiKSkpLCBhY3Rpb249InByZXBlbmQiKQpwaGVhdG1hcChwbG90X211bHRpbm9taWFsX2Nsb2NrbGlrZV9wcm9wb3J0aW9uc19hbmRfYWNjdXJhY3ksIAogICAgICAgIGNsdXN0ZXJfcm93cyA9IEZBTFNFLCBjbHVzdGVyX2NvbHMgPSBGQUxTRSwKICAgICAgICAjIGNvbCA9IHZpcmlkaXMoMTAwKSwKICAgICAgICBjb2xvciA9IGModmlyaWRpcygxMDApLCB2aXJpZGlzKDEwMClbMTAwXSksCiAgICAgICAgYnJlYWtzID0gYygwOjEwMCxtYXgocGxvdF9tdWx0aW5vbWlhbF9jbG9ja2xpa2VfcHJvcG9ydGlvbnNfYW5kX2FjY3VyYWN5KSksCiAgICAgICAgbWFpbiA9IHBhc3RlMCgiQXZlcmFnZSBlcnJvciByYXRlICglKSBvZiB0aW1pbmcgKG49IixzdGF0ZV90aW1pbmdfcmVwbGljYXRlcywiKSAtICIsIk11bHRpbm9taWFsIFNpbXVsYXRlZCBEYXRhIiksCiAgICAgICAgeGxhYiA9ICJQcm9wb3J0aW9uIG9mIGNsb2NrbGlrZSBtdXRhdGlvbnMgc2ltdWxhdGVkIiwKICAgICAgICB5bGFiID0gIkNvcHkgbnVtYmVyIHN0YXRlIGFuZCBvcmRlciIsCiAgICAgICAgYm9yZGVyX2NvbG9yID0gTkEsCiAgICAgICAgc2NhbGUgPSAibm9uZSIsCiAgICAgICAgZm9udHNpemVfcm93ID0gNykKc2V0SG9vaygiZ3JpZC5uZXdwYWdlIiwgTlVMTCwgInJlcGxhY2UiKQpncmlkLnRleHQoIlByb3BvcnRpb24gb2YgY2xvY2tsaWtlIG11dGF0aW9ucyBzaW11bGF0ZWQiLCB5PS0wLjAyLCBncD1ncGFyKGZvbnRzaXplPTE2KSkKZ3JpZC50ZXh0KCJDb3B5IG51bWJlciBzdGF0ZSBhbmQgb3JkZXIiLCB4PS0wLjA3LCByb3Q9OTAsIGdwPWdwYXIoZm9udHNpemU9MTYpKQpkZXYub2ZmKCkKYGBgCgojIyMgQ29ycmVjdCBvcmRlcnMgdiBjbG9ja2xpa2UgcHJvcG9ydGlvbgpgYGB7ciBmaWcuaGVpZ2h0PTEwfQpjb2xuYW1lcyhtdWx0aW5vbWlhbF9jbG9ja2xpa2VfcHJvcG9ydGlvbnNfYW5kX251bWJlcl9jb3JyZWN0X29yZGVyKSA8LSBnc3ViKCJYIiwiIixjb2xuYW1lcyhtdWx0aW5vbWlhbF9jbG9ja2xpa2VfcHJvcG9ydGlvbnNfYW5kX251bWJlcl9jb3JyZWN0X29yZGVyKSkKcGxvdF9tdWx0aW5vbWlhbF9jbG9ja2xpa2VfcHJvcG9ydGlvbnNfYW5kX251bWJlcl9jb3JyZWN0X29yZGVyIDwtIGFzLm1hdHJpeChtdWx0aW5vbWlhbF9jbG9ja2xpa2VfcHJvcG9ydGlvbnNfYW5kX251bWJlcl9jb3JyZWN0X29yZGVyKQpyb3duYW1lcyhwbG90X211bHRpbm9taWFsX2Nsb2NrbGlrZV9wcm9wb3J0aW9uc19hbmRfbnVtYmVyX2NvcnJlY3Rfb3JkZXIpIDwtIHJvd25hbWVzKG11bHRpbm9taWFsX2Nsb2NrbGlrZV9wcm9wb3J0aW9uc19hbmRfbnVtYmVyX2NvcnJlY3Rfb3JkZXIpCmBgYApgYGB7ciBmaWcuaGVpZ2h0PTEyfQpwbmcocGFzdGUwKG91dGRpciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJjbG9ja2xpa2VfcHJvcG9ydGlvbl9hbmRfY29ycmVjdF9vcmRlcl8iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbl9yZXBsaWNhdGVzX2Nsb2NrbGlrZSwiX3JlcGxpY2F0ZXMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbl9tdXRhdGlvbnNfY2xvY2tsaWtlX3Rlc3QsIl9tdXRhdGlvbnMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIl8iLCJtdWx0aW5vbWlhbF9kYXRhIiwiXyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTeXMuRGF0ZSgpLCIucG5nIiksCiAgICBoZWlnaHQgPSBmaWd1cmVfaGVpZ2h0LCB3aWR0aCA9IGZpZ3VyZV93aWR0aCwgcmVzID0gcmVzb2x1dGlvbiwgdW5pdHMgPSAiY20iKQpzZXRIb29rKCJncmlkLm5ld3BhZ2UiLCBmdW5jdGlvbigpIHB1c2hWaWV3cG9ydCh2aWV3cG9ydCh4PTEseT0xLHdpZHRoPTAuOSwgaGVpZ2h0PTAuOTUsIG5hbWU9InZwIiwganVzdD1jKCJyaWdodCIsInRvcCIpKSksIGFjdGlvbj0icHJlcGVuZCIpCnBoZWF0bWFwKHBsb3RfbXVsdGlub21pYWxfY2xvY2tsaWtlX3Byb3BvcnRpb25zX2FuZF9udW1iZXJfY29ycmVjdF9vcmRlciwgCiAgICAgICAgY2x1c3Rlcl9yb3dzID0gRkFMU0UsIGNsdXN0ZXJfY29scyA9IEZBTFNFLAogICAgICAgIGNvbCA9IHZpcmlkaXMoMTAwKSwKICAgICAgICBtYWluID0gcGFzdGUwKCJOdW1iZXIgb2YgY29ycmVjdCB0aW1pbmcgb3JkZXJzIChuPSIsc3RhdGVfdGltaW5nX3JlcGxpY2F0ZXMsIikgLSAiLCJNdWx0aW5vbWlhbCBTaW11bGF0ZWQgRGF0YSIpLAogICAgICAgIGJvcmRlcl9jb2xvciA9IE5BLAogICAgICAgIHNjYWxlID0gIm5vbmUiLAogICAgICAgIGZvbnRzaXplX3JvdyA9IDcpCnNldEhvb2soImdyaWQubmV3cGFnZSIsIE5VTEwsICJyZXBsYWNlIikKZ3JpZC50ZXh0KCJQcm9wb3J0aW9uIG9mIGNsb2NrbGlrZSBtdXRhdGlvbnMgc2ltdWxhdGVkIiwgeT0tMC4wMiwgZ3A9Z3Bhcihmb250c2l6ZT0xNikpCmdyaWQudGV4dCgiQ29weSBudW1iZXIgc3RhdGUgYW5kIG9yZGVyIiwgeD0tMC4wNywgcm90PTkwLCBncD1ncGFyKGZvbnRzaXplPTE2KSkKZGV2Lm9mZigpCmBgYAoKIyBDb21iaW5lZCBwbG90CiMjIyBQbG90dGluZyB0d28gZXJyb3IgcmF0ZWhlYXRtYXBzIHRvZ2V0aGVyCmBgYHtyfQptdXRfbnVtYmVyX2FjY3VyYWN5X2hlYXRtYXAgPC0gcGhlYXRtYXAocGxvdF9tdWx0aW5vbWlhbF9tdXRhdGlvbl9udW1iZXJfYW5kX2FjY3VyYWN5LCAKICAgICAgICBjbHVzdGVyX3Jvd3MgPSBGQUxTRSwgY2x1c3Rlcl9jb2xzID0gRkFMU0UsCiAgICAgICAgIyBjb2wgPSB2aXJpZGlzKDEwMCksCiAgICAgICAgY29sb3IgPSBjKHZpcmlkaXMoMTAwKSwgdmlyaWRpcygxMDApWzEwMF0pLAogICAgICAgIGJyZWFrcyA9IGMoMDoxMDAsbWF4KHBsb3RfbXVsdGlub21pYWxfbXV0YXRpb25fbnVtYmVyX2FuZF9hY2N1cmFjeSkpLAogICAgICAgIG1haW4gPSBwYXN0ZTAoIkF2ZXJhZ2UgZXJyb3IgcmF0ZSAoJSkgb2YgdGltaW5nIFxuKG49IixzdGF0ZV90aW1pbmdfcmVwbGljYXRlcywiKSIpLAogICAgICAgIHhsYWIgPSAiTnVtYmVyIG9mIG11dGF0aW9ucyBzaW11bGF0ZWQiLAogICAgICAgIHlsYWIgPSAiQ29weSBudW1iZXIgc3RhdGUgYW5kIG9yZGVyIiwKICAgICAgICBib3JkZXJfY29sb3IgPSBOQSwKICAgICAgICBzY2FsZSA9ICJub25lIiwKICAgICAgICBmb250c2l6ZSA9IDcpCmNsb2NrbGlrZV9hY2N1cmFjeV9oZWF0bWFwIDwtIHBoZWF0bWFwKHBsb3RfbXVsdGlub21pYWxfY2xvY2tsaWtlX3Byb3BvcnRpb25zX2FuZF9hY2N1cmFjeSwgCiAgICAgICAgY2x1c3Rlcl9yb3dzID0gRkFMU0UsIGNsdXN0ZXJfY29scyA9IEZBTFNFLAogICAgICAgICMgY29sID0gdmlyaWRpcygxMDApLAogICAgICAgIGNvbG9yID0gYyh2aXJpZGlzKDEwMCksIHZpcmlkaXMoMTAwKVsxMDBdKSwKICAgICAgICBicmVha3MgPSBjKDA6MTAwLG1heChwbG90X211bHRpbm9taWFsX2Nsb2NrbGlrZV9wcm9wb3J0aW9uc19hbmRfYWNjdXJhY3kpKSwKICAgICAgICBtYWluID0gcGFzdGUwKCJBdmVyYWdlIGVycm9yIHJhdGUgKCUpIG9mIHRpbWluZyBcbihuPSIsc3RhdGVfdGltaW5nX3JlcGxpY2F0ZXMsIikiKSwKICAgICAgICB4bGFiID0gIlByb3BvcnRpb24gb2YgY2xvY2tsaWtlIG11dGF0aW9ucyBzaW11bGF0ZWQiLAogICAgICAgIHlsYWIgPSAiQ29weSBudW1iZXIgc3RhdGUgYW5kIG9yZGVyIiwKICAgICAgICBib3JkZXJfY29sb3IgPSBOQSwKICAgICAgICBzY2FsZSA9ICJub25lIiwKICAgICAgICBmb250c2l6ZSA9IDcpCmBgYApgYGB7ciBmaWcuaGVpZ2h0PTEyfQpwbmcocGFzdGUwKG91dGRpciwibXV0YXRpb25fbnVtYmVyX2FuZF9lcnJvcl9yYXRlXyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0ZV90aW1pbmdfcmVwbGljYXRlcywiX3JlcGxpY2F0ZXMiLAogICAgICAgICAgICJjbG9ja2xpa2VfcHJvcG9ydGlvbl9hbmRfZXJyb3JfcmF0ZV8iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbl9yZXBsaWNhdGVzX2Nsb2NrbGlrZSwiX3JlcGxpY2F0ZXMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbl9tdXRhdGlvbnNfY2xvY2tsaWtlX3Rlc3QsIl9tdXRhdGlvbnMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIl8iLCJtdWx0aW5vbWlhbF9kYXRhIiwiXyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTeXMuRGF0ZSgpLCIucG5nIiksCiAgICBoZWlnaHQgPSBmaWd1cmVfaGVpZ2h0LCB3aWR0aCA9IGZpZ3VyZV93aWR0aCwgcmVzID0gcmVzb2x1dGlvbiwgdW5pdHMgPSAiY20iKQoKc2V0SG9vaygiZ3JpZC5uZXdwYWdlIiwgZnVuY3Rpb24oKSBwdXNoVmlld3BvcnQodmlld3BvcnQoeD0xLHk9MSx3aWR0aD0wLjk1LCBoZWlnaHQ9MC45NSwgbmFtZT0idnAiLCBqdXN0PWMoInJpZ2h0IiwidG9wIikpKSwgYWN0aW9uPSJwcmVwZW5kIikKZ3JpZC5hcnJhbmdlKGdyb2JzID0gbGlzdChtdXRfbnVtYmVyX2FjY3VyYWN5X2hlYXRtYXBbWzRdXSxjbG9ja2xpa2VfYWNjdXJhY3lfaGVhdG1hcFtbNF1dKSwKICAgICAgICAgICAgIG5jb2wgPSAyKQpzZXRIb29rKCJncmlkLm5ld3BhZ2UiLCBOVUxMLCAicmVwbGFjZSIpCmdyaWQudGV4dCgiTnVtYmVyIG9mIG11dGF0aW9ucyBzaW11bGF0ZWQiLCB5PS0wLjAyLCB4ID0gMC4yMiwgZ3A9Z3Bhcihmb250c2l6ZT0xMikpCmdyaWQudGV4dCgiUHJvcG9ydGlvbiBvZiBjbG9ja2xpa2UgbXV0YXRpb25zIHNpbXVsYXRlZCIsIHk9LTAuMDIsIHggPSAwLjczLCBncD1ncGFyKGZvbnRzaXplPTEyKSkKZ3JpZC50ZXh0KCJDb3B5IG51bWJlciBzdGF0ZSBhbmQgb3JkZXIiLCB4PS0wLjAyLCByb3Q9OTAsIGdwPWdwYXIoZm9udHNpemU9MTQpKQoKZ3JpZC50ZXh0KCJBIiwgeD0tMC4wMiwgeT0wLjk4LCBncD1ncGFyKGZvbnRzaXplPTE2KSkKZ3JpZC50ZXh0KCJCIiwgeD0wLjQ3LCB5PTAuOTgsIGdwPWdwYXIoZm9udHNpemU9MTYpKQoKZGV2Lm9mZigpCmBgYAoKIyMjIFBsb3R0aW5nIHR3byBvcmRlciBoZWF0bWFwcyB0b2dldGhlcgpgYGB7cn0KbXV0X251bWJlcl9vcmRlcl9oZWF0bWFwIDwtIHBoZWF0bWFwKHBsb3RfbXVsdGlub21pYWxfbXV0YXRpb25fbnVtYmVyX2FuZF9udW1iZXJfY29ycmVjdF9vcmRlciwgCiAgICAgICAgY2x1c3Rlcl9yb3dzID0gRkFMU0UsIGNsdXN0ZXJfY29scyA9IEZBTFNFLAogICAgICAgIGNvbCA9IHZpcmlkaXMoMTAwKSwKICAgICAgICBtYWluID0gcGFzdGUwKCJOdW1iZXIgb2YgY29ycmVjdCB0aW1pbmcgb3JkZXJzIFxuKG49IixzdGF0ZV90aW1pbmdfcmVwbGljYXRlcywiKSIpLAogICAgICAgIGJvcmRlcl9jb2xvciA9IE5BLAogICAgICAgIHNjYWxlID0gIm5vbmUiLAogICAgICAgIGZvbnRzaXplID0gNykKCmNsb2NrbGlrZV9vcmRlcl9oZWF0bWFwIDwtIHBoZWF0bWFwKHBsb3RfbXVsdGlub21pYWxfY2xvY2tsaWtlX3Byb3BvcnRpb25zX2FuZF9udW1iZXJfY29ycmVjdF9vcmRlciwgCiAgICAgICAgY2x1c3Rlcl9yb3dzID0gRkFMU0UsIGNsdXN0ZXJfY29scyA9IEZBTFNFLAogICAgICAgIGNvbCA9IHZpcmlkaXMoMTAwKSwKICAgICAgICBtYWluID0gcGFzdGUwKCJOdW1iZXIgb2YgY29ycmVjdCB0aW1pbmcgb3JkZXJzIFxuKG49IixzdGF0ZV90aW1pbmdfcmVwbGljYXRlcywiKSIpLAogICAgICAgIGJvcmRlcl9jb2xvciA9IE5BLAogICAgICAgIHNjYWxlID0gIm5vbmUiLAogICAgICAgIGZvbnRzaXplID0gNykKYGBgCmBgYHtyIGZpZy5oZWlnaHQ9MTJ9CnBuZyhwYXN0ZTAob3V0ZGlyLCJtdXRhdGlvbl9udW1iZXJfYW5kX2NvcnJlY3Rfb3JkZXJfIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXRlX3RpbWluZ19yZXBsaWNhdGVzLCJfcmVwbGljYXRlcyIsCiAgICAgICAgICAgImNsb2NrbGlrZV9wcm9wb3J0aW9uX2FuZF9jb3JyZWN0X29yZGVyXyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuX3JlcGxpY2F0ZXNfY2xvY2tsaWtlLCJfcmVwbGljYXRlcyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuX211dGF0aW9uc19jbG9ja2xpa2VfdGVzdCwiX211dGF0aW9ucyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiXyIsIm11bHRpbm9taWFsX2RhdGEiLCJfIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN5cy5EYXRlKCksIi5wbmciKSwKICAgIGhlaWdodCA9IGZpZ3VyZV9oZWlnaHQsIHdpZHRoID0gZmlndXJlX3dpZHRoLCByZXMgPSByZXNvbHV0aW9uLCB1bml0cyA9ICJjbSIpCgpzZXRIb29rKCJncmlkLm5ld3BhZ2UiLCBmdW5jdGlvbigpIHB1c2hWaWV3cG9ydCh2aWV3cG9ydCh4PTEseT0xLHdpZHRoPTAuOTUsIGhlaWdodD0wLjk1LCBuYW1lPSJ2cCIsIGp1c3Q9YygicmlnaHQiLCJ0b3AiKSkpLCBhY3Rpb249InByZXBlbmQiKQpncmlkLmFycmFuZ2UoZ3JvYnMgPSBsaXN0KG11dF9udW1iZXJfb3JkZXJfaGVhdG1hcFtbNF1dLGNsb2NrbGlrZV9vcmRlcl9oZWF0bWFwW1s0XV0pLAogICAgICAgICAgICAgbmNvbCA9IDIpCnNldEhvb2soImdyaWQubmV3cGFnZSIsIE5VTEwsICJyZXBsYWNlIikKZ3JpZC50ZXh0KCJOdW1iZXIgb2YgbXV0YXRpb25zIHNpbXVsYXRlZCIsIHk9LTAuMDIsIHggPSAwLjIyLCBncD1ncGFyKGZvbnRzaXplPTEyKSkKZ3JpZC50ZXh0KCJQcm9wb3J0aW9uIG9mIGNsb2NrbGlrZSBtdXRhdGlvbnMgc2ltdWxhdGVkIiwgeT0tMC4wMiwgeCA9IDAuNzMsIGdwPWdwYXIoZm9udHNpemU9MTIpKQpncmlkLnRleHQoIkNvcHkgbnVtYmVyIHN0YXRlIGFuZCBvcmRlciIsIHg9LTAuMDIsIHJvdD05MCwgZ3A9Z3Bhcihmb250c2l6ZT0xNCkpCgpncmlkLnRleHQoIkEiLCB4PS0wLjAyLCB5PTAuOTgsIGdwPWdwYXIoZm9udHNpemU9MTYpKQpncmlkLnRleHQoIkIiLCB4PTAuNDcsIHk9MC45OCwgZ3A9Z3Bhcihmb250c2l6ZT0xNikpCgpkZXYub2ZmKCkKYGBgCgoKIyBNaXNtYXRjaGVkIGVxdWF0aW9uIGRhdGEKVHJ5IG5ldyBwbG90dGluZyBhcHByb2FjaAoKIyMgNCt4ClJlYWQgaW4gc2FtcGxlIGRhdGEuCmBgYHtyfQpjbl80XzBfV0dHIDwtIHJlYWQuZGVsaW0ocGFzdGUwKHJlc3VsdHNfZGlyLCJhcHBseWluZ19yaWdodF9hbmRfd3JvbmdfZXF1YXRpb25zL3JpZ2h0X3ZzX3dyb25nX2VxdWF0aW9uc19zcGVhcm1hbl9jb3JyZWxhdGlvbl80KzAgV0dHXzEwMF9yZXBsaWNhdGVzMTAwX211dGF0aW9uc19tdWx0aW5vbWlhbF9kYXRhXzIwMjQtMDEtMDUudHh0IiksIGhlYWRlciA9IFRSVUUsIHNlcCA9ICJcdCIpCmNuXzRfMF9HVyA8LSByZWFkLmRlbGltKHBhc3RlMChyZXN1bHRzX2RpciwiYXBwbHlpbmdfcmlnaHRfYW5kX3dyb25nX2VxdWF0aW9ucy9yaWdodF92c193cm9uZ19lcXVhdGlvbnNfc3BlYXJtYW5fY29ycmVsYXRpb25fNCswIEdXXzEwMF9yZXBsaWNhdGVzMTAwX211dGF0aW9uc19tdWx0aW5vbWlhbF9kYXRhXzIwMjQtMDEtMDUudHh0IiksIGhlYWRlciA9IFRSVUUsIHNlcCA9ICJcdCIpCgpjbl80XzFfV0dHIDwtIHJlYWQuZGVsaW0ocGFzdGUwKHJlc3VsdHNfZGlyLCJhcHBseWluZ19yaWdodF9hbmRfd3JvbmdfZXF1YXRpb25zL3JpZ2h0X3ZzX3dyb25nX2VxdWF0aW9uc19zcGVhcm1hbl9jb3JyZWxhdGlvbl80KzEgV0dHXzEwMF9yZXBsaWNhdGVzMTAwX211dGF0aW9uc19tdWx0aW5vbWlhbF9kYXRhXzIwMjQtMDEtMDUudHh0IiksIGhlYWRlciA9IFRSVUUsIHNlcCA9ICJcdCIpCmNuXzRfMV9HVyA8LSByZWFkLmRlbGltKHBhc3RlMChyZXN1bHRzX2RpciwiYXBwbHlpbmdfcmlnaHRfYW5kX3dyb25nX2VxdWF0aW9ucy9yaWdodF92c193cm9uZ19lcXVhdGlvbnNfc3BlYXJtYW5fY29ycmVsYXRpb25fNCsxIEdXXzEwMF9yZXBsaWNhdGVzMTAwX211dGF0aW9uc19tdWx0aW5vbWlhbF9kYXRhXzIwMjQtMDEtMDUudHh0IiksIGhlYWRlciA9IFRSVUUsIHNlcCA9ICJcdCIpCgpjbl80XzJfV0dHIDwtIHJlYWQuZGVsaW0ocGFzdGUwKHJlc3VsdHNfZGlyLCJhcHBseWluZ19yaWdodF9hbmRfd3JvbmdfZXF1YXRpb25zL3JpZ2h0X3ZzX3dyb25nX2VxdWF0aW9uc19zcGVhcm1hbl9jb3JyZWxhdGlvbl80KzIgV0dHXzEwMF9yZXBsaWNhdGVzMTAwX211dGF0aW9uc19tdWx0aW5vbWlhbF9kYXRhXzIwMjQtMDEtMDUudHh0IiksIGhlYWRlciA9IFRSVUUsIHNlcCA9ICJcdCIpCmNuXzRfMl9HVyA8LSByZWFkLmRlbGltKHBhc3RlMChyZXN1bHRzX2RpciwiYXBwbHlpbmdfcmlnaHRfYW5kX3dyb25nX2VxdWF0aW9ucy9yaWdodF92c193cm9uZ19lcXVhdGlvbnNfc3BlYXJtYW5fY29ycmVsYXRpb25fNCsyIEdXXzEwMF9yZXBsaWNhdGVzMTAwX211dGF0aW9uc19tdWx0aW5vbWlhbF9kYXRhXzIwMjQtMDEtMDUudHh0IiksIGhlYWRlciA9IFRSVUUsIHNlcCA9ICJcdCIpCmBgYApgYGB7cn0KY25fNF94IDwtIHJiaW5kKGNuXzRfMF9XR0csIGNuXzRfMF9HVywKICAgICAgICAgICAgICAgIGNuXzRfMV9XR0csIGNuXzRfMV9HVywKICAgICAgICAgICAgICAgIGNuXzRfMl9XR0csIGNuXzRfMl9HVykKYGBgCgpgYGB7cn0KY25fNF94JFNpZ25pZmljYW5jZSA8LSBpZmVsc2UoY25fNF94JFNwZWFybWFuX2FkanVzdGVkX3AgPCAwLjA1LCAiU2lnbmlmaWNhbnQiLCJOb3QgXG5TaWduaWZpY2FudCIpCmBgYAoKCmBgYHtyfQpjbl80X3hfcGVhcnNvbl9wbG90IDwtIGdncGxvdChjbl80X3gsIGFlcyh4ID0gVHJ1ZV9vcmRlciwgeSA9IEFwcGxpZWRfb3JkZXIsIGZpbGwgPSBTcGVhcm1hbl9yaG8pKSsKICBnZW9tX3RpbGUoYWVzKGNvbG9yPWFzLmZhY3RvcihTaWduaWZpY2FuY2UpLCB3aWR0aD0wLjksIGhlaWdodD0wLjkpLCBzaXplPTAuMykrCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBjKCJmaXJlYnJpY2siLCJyb3lhbGJsdWUiLCJncmV5IiksIGxpbWl0cyA9IGMoIlNpZ25pZmljYW50IiwiXG5Ob3QgU2lnbmlmaWNhbnQiLE5BKSwgbmFtZSA9ICJBZGp1c3RlZCBwIikrCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbD1yb3VuZChTcGVhcm1hbl9yaG8sZGlnaXRzID0gMikpLCBzaXplID0gMikrCiAgZmFjZXRfZ3JpZChyb3dzID0gdmFycyhUaW1lcG9pbnQpLCBjb2xzID0gdmFycyhDTl9zdGF0ZSkpKwogICMgc2NhbGVfZmlsbF9ncmFkaWVudG4oY29sb3JzID0gdmlyaWRpc19wYWwob3B0aW9uID0gIm1hZ21hIikoMTAwKSwgbGltaXRzPWMoLTEsIDEpLCAKICAjICAgICAgICAgICAgICAgICAgICAgIG5hLnZhbHVlID0gImdyZXkiKSsKICBzY2FsZV9maWxsX2Rpc3RpbGxlcihwYWxldHRlID0gIlJkQnUiLCBsaW1pdHMgPSBjKC0xLDEpLCBuYW1lID0gIlNwZWFybWFuIM+BIikrCiAgIyBzY2FsZV9maWxsX3ZpcmlkaXMob3B0aW9uID0gIm1hZ21hIikrCiAgdGhlbWVfbWluaW1hbCgpKwogIHlsYWIoIkFwcGxpZWQgdGltaW5nIG9yZGVyIikrCiAgeGxhYigiVHJ1ZSBzaW11bGF0ZWQgdGltaW5nIG9yZGVyIikKY25fNF94X3BlYXJzb25fcGxvdApgYGAKCiMjIDUreApSZWFkIGluIHNhbXBsZSBkYXRhLgpgYGB7cn0KY25fNV8wX1dHR0cgPC0gcmVhZC5kZWxpbShwYXN0ZTAocmVzdWx0c19kaXIsImFwcGx5aW5nX3JpZ2h0X2FuZF93cm9uZ19lcXVhdGlvbnMvcmlnaHRfdnNfd3JvbmdfZXF1YXRpb25zX3NwZWFybWFuX2NvcnJlbGF0aW9uXzUrMCBXR0dHXzEwMF9yZXBsaWNhdGVzMTAwX211dGF0aW9uc19tdWx0aW5vbWlhbF9kYXRhXzIwMjQtMDEtMDUudHh0IiksIGhlYWRlciA9IFRSVUUsIHNlcCA9ICJcdCIpCmNuXzVfMF9HV0cgPC0gcmVhZC5kZWxpbShwYXN0ZTAocmVzdWx0c19kaXIsImFwcGx5aW5nX3JpZ2h0X2FuZF93cm9uZ19lcXVhdGlvbnMvcmlnaHRfdnNfd3JvbmdfZXF1YXRpb25zX3NwZWFybWFuX2NvcnJlbGF0aW9uXzUrMCBHV0dfMTAwX3JlcGxpY2F0ZXMxMDBfbXV0YXRpb25zX211bHRpbm9taWFsX2RhdGFfMjAyNC0wMS0wNS50eHQiKSwgaGVhZGVyID0gVFJVRSwgc2VwID0gIlx0IikKCmNuXzVfMV9XR0dHIDwtIHJlYWQuZGVsaW0ocGFzdGUwKHJlc3VsdHNfZGlyLCJhcHBseWluZ19yaWdodF9hbmRfd3JvbmdfZXF1YXRpb25zL3JpZ2h0X3ZzX3dyb25nX2VxdWF0aW9uc19zcGVhcm1hbl9jb3JyZWxhdGlvbl81KzEgV0dHR18xMDBfcmVwbGljYXRlczEwMF9tdXRhdGlvbnNfbXVsdGlub21pYWxfZGF0YV8yMDI0LTAxLTA1LnR4dCIpLCBoZWFkZXIgPSBUUlVFLCBzZXAgPSAiXHQiKQpjbl81XzFfR1dHIDwtIHJlYWQuZGVsaW0ocGFzdGUwKHJlc3VsdHNfZGlyLCJhcHBseWluZ19yaWdodF9hbmRfd3JvbmdfZXF1YXRpb25zL3JpZ2h0X3ZzX3dyb25nX2VxdWF0aW9uc19zcGVhcm1hbl9jb3JyZWxhdGlvbl81KzEgR1dHXzEwMF9yZXBsaWNhdGVzMTAwX211dGF0aW9uc19tdWx0aW5vbWlhbF9kYXRhXzIwMjQtMDEtMDUudHh0IiksIGhlYWRlciA9IFRSVUUsIHNlcCA9ICJcdCIpCgpjbl81XzJfV0dHRyA8LSByZWFkLmRlbGltKHBhc3RlMChyZXN1bHRzX2RpciwiYXBwbHlpbmdfcmlnaHRfYW5kX3dyb25nX2VxdWF0aW9ucy9yaWdodF92c193cm9uZ19lcXVhdGlvbnNfc3BlYXJtYW5fY29ycmVsYXRpb25fNSsyIFdHR0dfMTAwX3JlcGxpY2F0ZXMxMDBfbXV0YXRpb25zX211bHRpbm9taWFsX2RhdGFfMjAyNC0wMS0wNS50eHQiKSwgaGVhZGVyID0gVFJVRSwgc2VwID0gIlx0IikKY25fNV8yX0dXRyA8LSByZWFkLmRlbGltKHBhc3RlMChyZXN1bHRzX2RpciwiYXBwbHlpbmdfcmlnaHRfYW5kX3dyb25nX2VxdWF0aW9ucy9yaWdodF92c193cm9uZ19lcXVhdGlvbnNfc3BlYXJtYW5fY29ycmVsYXRpb25fNSsyIEdXR18xMDBfcmVwbGljYXRlczEwMF9tdXRhdGlvbnNfbXVsdGlub21pYWxfZGF0YV8yMDI0LTAxLTA1LnR4dCIpLCBoZWFkZXIgPSBUUlVFLCBzZXAgPSAiXHQiKQpgYGAKYGBge3J9CmNuXzVfeCA8LSByYmluZChjbl81XzBfV0dHRywgY25fNV8wX0dXRywKICAgICAgICAgICAgICAgIGNuXzVfMV9XR0dHLCBjbl81XzFfR1dHLAogICAgICAgICAgICAgICAgY25fNV8yX1dHR0csIGNuXzVfMl9HV0cpCmBgYAoKYGBge3J9CmNuXzVfeCRTaWduaWZpY2FuY2UgPC0gaWZlbHNlKGNuXzVfeCRTcGVhcm1hbl9hZGp1c3RlZF9wIDwgMC4wNSwgIlNpZ25pZmljYW50IiwiTm90IFNpZ25pZmljYW50IikKYGBgCgoKYGBge3J9CmNuXzVfeF9wZWFyc29uX3Bsb3QgPC0gZ2dwbG90KGNuXzVfeCwgYWVzKHggPSBUcnVlX29yZGVyLCB5ID0gQXBwbGllZF9vcmRlciwgZmlsbCA9IFNwZWFybWFuX3JobykpKwogIGdlb21fdGlsZShhZXMoY29sb3I9YXMuZmFjdG9yKFNpZ25pZmljYW5jZSksIHdpZHRoPTAuOSwgaGVpZ2h0PTAuOSksIHNpemU9MC4zKSsKICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IGMoImZpcmVicmljayIsInJveWFsYmx1ZSIsImdyZXkiKSwgbGltaXRzID0gYygiU2lnbmlmaWNhbnQiLCJOb3QgU2lnbmlmaWNhbnQiLE5BKSwgbmFtZSA9ICJBZGp1c3RlZCBwIikrCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbD1yb3VuZChTcGVhcm1hbl9yaG8sZGlnaXRzID0gMikpLCBzaXplID0gMikrCiAgZmFjZXRfZ3JpZChyb3dzID0gdmFycyhUaW1lcG9pbnQpLCBjb2xzID0gdmFycyhDTl9zdGF0ZSkpKwogICMgc2NhbGVfZmlsbF9ncmFkaWVudG4oY29sb3JzID0gdmlyaWRpc19wYWwob3B0aW9uID0gIm1hZ21hIikoMTAwKSwgbGltaXRzPWMoLTEsIDEpLCAKICAjICAgICAgICAgICAgICAgICAgICAgIG5hLnZhbHVlID0gImdyZXkiKSsKICBzY2FsZV9maWxsX2Rpc3RpbGxlcihwYWxldHRlID0gIlJkQnUiLCBsaW1pdHMgPSBjKC0xLDEpLCBuYW1lID0gIlNwZWFybWFuIM+BIikrCiAgIyBzY2FsZV9maWxsX3ZpcmlkaXMob3B0aW9uID0gIm1hZ21hIikrCiAgdGhlbWVfbWluaW1hbCgpKwogIHlsYWIoIkFwcGxpZWQgdGltaW5nIG9yZGVyIikrCiAgeGxhYigiVHJ1ZSBzaW11bGF0ZWQgdGltaW5nIG9yZGVyIikKY25fNV94X3BlYXJzb25fcGxvdApgYGAKCiMjIDYreApSZWFkIGluIHNhbXBsZSBkYXRhLgpgYGB7cn0KY25fNl8wX1dHR0dHIDwtIHJlYWQuZGVsaW0ocGFzdGUwKHJlc3VsdHNfZGlyLCJhcHBseWluZ19yaWdodF9hbmRfd3JvbmdfZXF1YXRpb25zL3JpZ2h0X3ZzX3dyb25nX2VxdWF0aW9uc19zcGVhcm1hbl9jb3JyZWxhdGlvbl82KzAgV0dHR0dfMTAwX3JlcGxpY2F0ZXMxMDBfbXV0YXRpb25zX211bHRpbm9taWFsX2RhdGFfMjAyNC0wMS0wNS50eHQiKSwgaGVhZGVyID0gVFJVRSwgc2VwID0gIlx0IikKY25fNl8wX0dXR0cgPC0gcmVhZC5kZWxpbShwYXN0ZTAocmVzdWx0c19kaXIsImFwcGx5aW5nX3JpZ2h0X2FuZF93cm9uZ19lcXVhdGlvbnMvcmlnaHRfdnNfd3JvbmdfZXF1YXRpb25zX3NwZWFybWFuX2NvcnJlbGF0aW9uXzYrMCBHV0dHXzEwMF9yZXBsaWNhdGVzMTAwX211dGF0aW9uc19tdWx0aW5vbWlhbF9kYXRhXzIwMjQtMDEtMDUudHh0IiksIGhlYWRlciA9IFRSVUUsIHNlcCA9ICJcdCIpCmNuXzZfMF9HR1cgPC0gcmVhZC5kZWxpbShwYXN0ZTAocmVzdWx0c19kaXIsImFwcGx5aW5nX3JpZ2h0X2FuZF93cm9uZ19lcXVhdGlvbnMvcmlnaHRfdnNfd3JvbmdfZXF1YXRpb25zX3NwZWFybWFuX2NvcnJlbGF0aW9uXzYrMCBHR1dfMTAwX3JlcGxpY2F0ZXMxMDBfbXV0YXRpb25zX211bHRpbm9taWFsX2RhdGFfMjAyNC0wMS0wNS50eHQiKSwgaGVhZGVyID0gVFJVRSwgc2VwID0gIlx0IikKCmNuXzZfMV9XR0dHRyA8LSByZWFkLmRlbGltKHBhc3RlMChyZXN1bHRzX2RpciwiYXBwbHlpbmdfcmlnaHRfYW5kX3dyb25nX2VxdWF0aW9ucy9yaWdodF92c193cm9uZ19lcXVhdGlvbnNfc3BlYXJtYW5fY29ycmVsYXRpb25fNisxIFdHR0dHXzEwMF9yZXBsaWNhdGVzMTAwX211dGF0aW9uc19tdWx0aW5vbWlhbF9kYXRhXzIwMjQtMDEtMDUudHh0IiksIGhlYWRlciA9IFRSVUUsIHNlcCA9ICJcdCIpCmNuXzZfMV9HV0dHIDwtIHJlYWQuZGVsaW0ocGFzdGUwKHJlc3VsdHNfZGlyLCJhcHBseWluZ19yaWdodF9hbmRfd3JvbmdfZXF1YXRpb25zL3JpZ2h0X3ZzX3dyb25nX2VxdWF0aW9uc19zcGVhcm1hbl9jb3JyZWxhdGlvbl82KzEgR1dHR18xMDBfcmVwbGljYXRlczEwMF9tdXRhdGlvbnNfbXVsdGlub21pYWxfZGF0YV8yMDI0LTAxLTA1LnR4dCIpLCBoZWFkZXIgPSBUUlVFLCBzZXAgPSAiXHQiKQpjbl82XzFfR0dXIDwtIHJlYWQuZGVsaW0ocGFzdGUwKHJlc3VsdHNfZGlyLCJhcHBseWluZ19yaWdodF9hbmRfd3JvbmdfZXF1YXRpb25zL3JpZ2h0X3ZzX3dyb25nX2VxdWF0aW9uc19zcGVhcm1hbl9jb3JyZWxhdGlvbl82KzEgR0dXXzEwMF9yZXBsaWNhdGVzMTAwX211dGF0aW9uc19tdWx0aW5vbWlhbF9kYXRhXzIwMjQtMDEtMDUudHh0IiksIGhlYWRlciA9IFRSVUUsIHNlcCA9ICJcdCIpCgpjbl82XzJfV0dHR0cgPC0gcmVhZC5kZWxpbShwYXN0ZTAocmVzdWx0c19kaXIsImFwcGx5aW5nX3JpZ2h0X2FuZF93cm9uZ19lcXVhdGlvbnMvcmlnaHRfdnNfd3JvbmdfZXF1YXRpb25zX3NwZWFybWFuX2NvcnJlbGF0aW9uXzYrMiBXR0dHR18xMDBfcmVwbGljYXRlczEwMF9tdXRhdGlvbnNfbXVsdGlub21pYWxfZGF0YV8yMDI0LTAxLTA1LnR4dCIpLCBoZWFkZXIgPSBUUlVFLCBzZXAgPSAiXHQiKQpjbl82XzJfR1dHRyA8LSByZWFkLmRlbGltKHBhc3RlMChyZXN1bHRzX2RpciwiYXBwbHlpbmdfcmlnaHRfYW5kX3dyb25nX2VxdWF0aW9ucy9yaWdodF92c193cm9uZ19lcXVhdGlvbnNfc3BlYXJtYW5fY29ycmVsYXRpb25fNisyIEdXR0dfMTAwX3JlcGxpY2F0ZXMxMDBfbXV0YXRpb25zX211bHRpbm9taWFsX2RhdGFfMjAyNC0wMS0wNS50eHQiKSwgaGVhZGVyID0gVFJVRSwgc2VwID0gIlx0IikKY25fNl8yX0dHVyA8LSByZWFkLmRlbGltKHBhc3RlMChyZXN1bHRzX2RpciwiYXBwbHlpbmdfcmlnaHRfYW5kX3dyb25nX2VxdWF0aW9ucy9yaWdodF92c193cm9uZ19lcXVhdGlvbnNfc3BlYXJtYW5fY29ycmVsYXRpb25fNisyIEdHV18xMDBfcmVwbGljYXRlczEwMF9tdXRhdGlvbnNfbXVsdGlub21pYWxfZGF0YV8yMDI0LTAxLTA1LnR4dCIpLCBoZWFkZXIgPSBUUlVFLCBzZXAgPSAiXHQiKQpgYGAKYGBge3J9CmNuXzZfeCA8LSByYmluZChjbl82XzBfV0dHR0csIGNuXzZfMF9HV0dHLCBjbl82XzBfR0dXLAogICAgICAgICAgICAgICAgY25fNl8xX1dHR0dHLCBjbl82XzFfR1dHRywgY25fNl8xX0dHVywKICAgICAgICAgICAgICAgIGNuXzZfMl9XR0dHRywgY25fNl8yX0dXR0csIGNuXzZfMl9HR1cpCmBgYAoKYGBge3J9CmNuXzZfeCRTaWduaWZpY2FuY2UgPC0gaWZlbHNlKGNuXzZfeCRTcGVhcm1hbl9hZGp1c3RlZF9wIDwgMC4wNSwgIlNpZ25pZmljYW50IiwiTm90IFNpZ25pZmljYW50IikKYGBgCgoKYGBge3J9CmNuXzZfeF9wZWFyc29uX3Bsb3QgPC0gZ2dwbG90KGNuXzZfeCwgYWVzKHggPSBUcnVlX29yZGVyLCB5ID0gQXBwbGllZF9vcmRlciwgZmlsbCA9IFNwZWFybWFuX3JobykpKwogIGdlb21fdGlsZShhZXMoY29sb3I9YXMuZmFjdG9yKFNpZ25pZmljYW5jZSksIHdpZHRoPTAuOSwgaGVpZ2h0PTAuOSksIHNpemU9MC4zKSsKICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IGMoImZpcmVicmljayIsInJveWFsYmx1ZSIsImdyZXkiKSwgbGltaXRzID0gYygiU2lnbmlmaWNhbnQiLCJOb3QgU2lnbmlmaWNhbnQiLE5BKSwgbmFtZSA9ICJBZGp1c3RlZCBwIikrCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbD1yb3VuZChTcGVhcm1hbl9yaG8sZGlnaXRzID0gMikpLCBzaXplID0gMikrCiAgZmFjZXRfZ3JpZChyb3dzID0gdmFycyhUaW1lcG9pbnQpLCBjb2xzID0gdmFycyhDTl9zdGF0ZSkpKwogICMgc2NhbGVfZmlsbF9ncmFkaWVudG4oY29sb3JzID0gdmlyaWRpc19wYWwob3B0aW9uID0gIm1hZ21hIikoMTAwKSwgbGltaXRzPWMoLTEsIDEpLCAKICAjICAgICAgICAgICAgICAgICAgICAgIG5hLnZhbHVlID0gImdyZXkiKSsKICBzY2FsZV9maWxsX2Rpc3RpbGxlcihwYWxldHRlID0gIlJkQnUiLCBsaW1pdHMgPSBjKC0xLDEpLCBuYW1lID0gIlNwZWFybWFuIM+BIikrCiAgIyBzY2FsZV9maWxsX3ZpcmlkaXMob3B0aW9uID0gIm1hZ21hIikrCiAgdGhlbWVfbWluaW1hbCgpKwogIHlsYWIoIkFwcGxpZWQgdGltaW5nIG9yZGVyIikrCiAgeGxhYigiVHJ1ZSBzaW11bGF0ZWQgdGltaW5nIG9yZGVyIikKY25fNl94X3BlYXJzb25fcGxvdApgYGAKCiMjIDcreApSZWFkIGluIHNhbXBsZSBkYXRhLgpgYGB7cn0KY25fN18wX1dHR0dHRyA8LSByZWFkLmRlbGltKHBhc3RlMChyZXN1bHRzX2RpciwiYXBwbHlpbmdfcmlnaHRfYW5kX3dyb25nX2VxdWF0aW9ucy9yaWdodF92c193cm9uZ19lcXVhdGlvbnNfc3BlYXJtYW5fY29ycmVsYXRpb25fNyswIFdHR0dHR18xMDBfcmVwbGljYXRlczEwMF9tdXRhdGlvbnNfbXVsdGlub21pYWxfZGF0YV8yMDI0LTAxLTA1LnR4dCIpLCBoZWFkZXIgPSBUUlVFLCBzZXAgPSAiXHQiKQpjbl83XzBfR1dHR0cgPC0gcmVhZC5kZWxpbShwYXN0ZTAocmVzdWx0c19kaXIsImFwcGx5aW5nX3JpZ2h0X2FuZF93cm9uZ19lcXVhdGlvbnMvcmlnaHRfdnNfd3JvbmdfZXF1YXRpb25zX3NwZWFybWFuX2NvcnJlbGF0aW9uXzcrMCBHV0dHR18xMDBfcmVwbGljYXRlczEwMF9tdXRhdGlvbnNfbXVsdGlub21pYWxfZGF0YV8yMDI0LTAxLTA1LnR4dCIpLCBoZWFkZXIgPSBUUlVFLCBzZXAgPSAiXHQiKQpjbl83XzBfR0dXRyA8LSByZWFkLmRlbGltKHBhc3RlMChyZXN1bHRzX2RpciwiYXBwbHlpbmdfcmlnaHRfYW5kX3dyb25nX2VxdWF0aW9ucy9yaWdodF92c193cm9uZ19lcXVhdGlvbnNfc3BlYXJtYW5fY29ycmVsYXRpb25fNyswIEdHV0dfMTAwX3JlcGxpY2F0ZXMxMDBfbXV0YXRpb25zX211bHRpbm9taWFsX2RhdGFfMjAyNC0wMS0wNS50eHQiKSwgaGVhZGVyID0gVFJVRSwgc2VwID0gIlx0IikKCmNuXzdfMV9XR0dHR0cgPC0gcmVhZC5kZWxpbShwYXN0ZTAocmVzdWx0c19kaXIsImFwcGx5aW5nX3JpZ2h0X2FuZF93cm9uZ19lcXVhdGlvbnMvcmlnaHRfdnNfd3JvbmdfZXF1YXRpb25zX3NwZWFybWFuX2NvcnJlbGF0aW9uXzcrMSBXR0dHR0dfMTAwX3JlcGxpY2F0ZXMxMDBfbXV0YXRpb25zX211bHRpbm9taWFsX2RhdGFfMjAyNC0wMS0wNS50eHQiKSwgaGVhZGVyID0gVFJVRSwgc2VwID0gIlx0IikKY25fN18xX0dXR0dHIDwtIHJlYWQuZGVsaW0ocGFzdGUwKHJlc3VsdHNfZGlyLCJhcHBseWluZ19yaWdodF9hbmRfd3JvbmdfZXF1YXRpb25zL3JpZ2h0X3ZzX3dyb25nX2VxdWF0aW9uc19zcGVhcm1hbl9jb3JyZWxhdGlvbl83KzEgR1dHR0dfMTAwX3JlcGxpY2F0ZXMxMDBfbXV0YXRpb25zX211bHRpbm9taWFsX2RhdGFfMjAyNC0wMS0wNS50eHQiKSwgaGVhZGVyID0gVFJVRSwgc2VwID0gIlx0IikKY25fN18xX0dHV0cgPC0gcmVhZC5kZWxpbShwYXN0ZTAocmVzdWx0c19kaXIsImFwcGx5aW5nX3JpZ2h0X2FuZF93cm9uZ19lcXVhdGlvbnMvcmlnaHRfdnNfd3JvbmdfZXF1YXRpb25zX3NwZWFybWFuX2NvcnJlbGF0aW9uXzcrMSBHR1dHXzEwMF9yZXBsaWNhdGVzMTAwX211dGF0aW9uc19tdWx0aW5vbWlhbF9kYXRhXzIwMjQtMDEtMDUudHh0IiksIGhlYWRlciA9IFRSVUUsIHNlcCA9ICJcdCIpCgpjbl83XzJfV0dHR0dHIDwtIHJlYWQuZGVsaW0ocGFzdGUwKHJlc3VsdHNfZGlyLCJhcHBseWluZ19yaWdodF9hbmRfd3JvbmdfZXF1YXRpb25zL3JpZ2h0X3ZzX3dyb25nX2VxdWF0aW9uc19zcGVhcm1hbl9jb3JyZWxhdGlvbl83KzIgV0dHR0dHXzEwMF9yZXBsaWNhdGVzMTAwX211dGF0aW9uc19tdWx0aW5vbWlhbF9kYXRhXzIwMjQtMDEtMDUudHh0IiksIGhlYWRlciA9IFRSVUUsIHNlcCA9ICJcdCIpCmNuXzdfMl9HV0dHRyA8LSByZWFkLmRlbGltKHBhc3RlMChyZXN1bHRzX2RpciwiYXBwbHlpbmdfcmlnaHRfYW5kX3dyb25nX2VxdWF0aW9ucy9yaWdodF92c193cm9uZ19lcXVhdGlvbnNfc3BlYXJtYW5fY29ycmVsYXRpb25fNysyIEdXR0dHXzEwMF9yZXBsaWNhdGVzMTAwX211dGF0aW9uc19tdWx0aW5vbWlhbF9kYXRhXzIwMjQtMDEtMDUudHh0IiksIGhlYWRlciA9IFRSVUUsIHNlcCA9ICJcdCIpCmNuXzdfMl9HR1dHIDwtIHJlYWQuZGVsaW0ocGFzdGUwKHJlc3VsdHNfZGlyLCJhcHBseWluZ19yaWdodF9hbmRfd3JvbmdfZXF1YXRpb25zL3JpZ2h0X3ZzX3dyb25nX2VxdWF0aW9uc19zcGVhcm1hbl9jb3JyZWxhdGlvbl83KzIgR0dXR18xMDBfcmVwbGljYXRlczEwMF9tdXRhdGlvbnNfbXVsdGlub21pYWxfZGF0YV8yMDI0LTAxLTA1LnR4dCIpLCBoZWFkZXIgPSBUUlVFLCBzZXAgPSAiXHQiKQpgYGAKYGBge3J9CmNuXzdfeCA8LSByYmluZChjbl83XzBfV0dHR0dHLCBjbl83XzBfR1dHR0csIGNuXzdfMF9HR1dHLAogICAgICAgICAgICAgICAgY25fN18xX1dHR0dHRywgY25fN18xX0dXR0dHLCBjbl83XzFfR0dXRywKICAgICAgICAgICAgICAgIGNuXzdfMl9XR0dHR0csIGNuXzdfMl9HV0dHRywgY25fN18yX0dHV0cpCmBgYAoKYGBge3J9CmNuXzdfeCRTaWduaWZpY2FuY2UgPC0gaWZlbHNlKGNuXzdfeCRTcGVhcm1hbl9hZGp1c3RlZF9wIDwgMC4wNSwgIlNpZ25pZmljYW50IiwiTm90IFNpZ25pZmljYW50IikKYGBgCgoKYGBge3J9CmNuXzdfeF9wZWFyc29uX3Bsb3QgPC0gZ2dwbG90KGNuXzdfeCwgYWVzKHggPSBUcnVlX29yZGVyLCB5ID0gQXBwbGllZF9vcmRlciwgZmlsbCA9IFNwZWFybWFuX3JobykpKwogIGdlb21fdGlsZShhZXMoY29sb3I9YXMuZmFjdG9yKFNpZ25pZmljYW5jZSksIHdpZHRoPTAuOSwgaGVpZ2h0PTAuOSksIHNpemU9MC4zKSsKICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IGMoImZpcmVicmljayIsInJveWFsYmx1ZSIsImdyZXkiKSwgbGltaXRzID0gYygiU2lnbmlmaWNhbnQiLCJOb3QgU2lnbmlmaWNhbnQiLE5BKSwgbmFtZSA9ICJBZGp1c3RlZCBwIikrCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbD1yb3VuZChTcGVhcm1hbl9yaG8sZGlnaXRzID0gMikpLCBzaXplID0gMikrCiAgZmFjZXRfZ3JpZChyb3dzID0gdmFycyhUaW1lcG9pbnQpLCBjb2xzID0gdmFycyhDTl9zdGF0ZSkpKwogICMgc2NhbGVfZmlsbF9ncmFkaWVudG4oY29sb3JzID0gdmlyaWRpc19wYWwob3B0aW9uID0gIm1hZ21hIikoMTAwKSwgbGltaXRzPWMoLTEsIDEpLCAKICAjICAgICAgICAgICAgICAgICAgICAgIG5hLnZhbHVlID0gImdyZXkiKSsKICBzY2FsZV9maWxsX2Rpc3RpbGxlcihwYWxldHRlID0gIlJkQnUiLCBsaW1pdHMgPSBjKC0xLDEpLCBuYW1lID0gIlNwZWFybWFuIM+BIikrCiAgIyBzY2FsZV9maWxsX3ZpcmlkaXMob3B0aW9uID0gIm1hZ21hIikrCiAgdGhlbWVfbWluaW1hbCgpKwogIHlsYWIoIkFwcGxpZWQgdGltaW5nIG9yZGVyIikrCiAgeGxhYigiVHJ1ZSBzaW11bGF0ZWQgdGltaW5nIG9yZGVyIikKY25fN194X3BlYXJzb25fcGxvdApgYGAKCiMjIDgreApSZWFkIGluIHNhbXBsZSBkYXRhLgpgYGB7cn0KY25fOF8wX1dHR0dHR0cgPC0gcmVhZC5kZWxpbShwYXN0ZTAocmVzdWx0c19kaXIsImFwcGx5aW5nX3JpZ2h0X2FuZF93cm9uZ19lcXVhdGlvbnMvcmlnaHRfdnNfd3JvbmdfZXF1YXRpb25zX3NwZWFybWFuX2NvcnJlbGF0aW9uXzgrMCBXR0dHR0dHXzEwMF9yZXBsaWNhdGVzMTAwX211dGF0aW9uc19tdWx0aW5vbWlhbF9kYXRhXzIwMjQtMDEtMDUudHh0IiksIGhlYWRlciA9IFRSVUUsIHNlcCA9ICJcdCIpCmNuXzhfMF9HV0dHR0cgPC0gcmVhZC5kZWxpbShwYXN0ZTAocmVzdWx0c19kaXIsImFwcGx5aW5nX3JpZ2h0X2FuZF93cm9uZ19lcXVhdGlvbnMvcmlnaHRfdnNfd3JvbmdfZXF1YXRpb25zX3NwZWFybWFuX2NvcnJlbGF0aW9uXzgrMCBHV0dHR0dfMTAwX3JlcGxpY2F0ZXMxMDBfbXV0YXRpb25zX211bHRpbm9taWFsX2RhdGFfMjAyNC0wMS0wNS50eHQiKSwgaGVhZGVyID0gVFJVRSwgc2VwID0gIlx0IikKY25fOF8wX0dHV0dHIDwtIHJlYWQuZGVsaW0ocGFzdGUwKHJlc3VsdHNfZGlyLCJhcHBseWluZ19yaWdodF9hbmRfd3JvbmdfZXF1YXRpb25zL3JpZ2h0X3ZzX3dyb25nX2VxdWF0aW9uc19zcGVhcm1hbl9jb3JyZWxhdGlvbl84KzAgR0dXR0dfMTAwX3JlcGxpY2F0ZXMxMDBfbXV0YXRpb25zX211bHRpbm9taWFsX2RhdGFfMjAyNC0wMS0wNS50eHQiKSwgaGVhZGVyID0gVFJVRSwgc2VwID0gIlx0IikKY25fOF8wX0dHR1cgPC0gcmVhZC5kZWxpbShwYXN0ZTAocmVzdWx0c19kaXIsImFwcGx5aW5nX3JpZ2h0X2FuZF93cm9uZ19lcXVhdGlvbnMvcmlnaHRfdnNfd3JvbmdfZXF1YXRpb25zX3NwZWFybWFuX2NvcnJlbGF0aW9uXzgrMCBHR0dXXzEwMF9yZXBsaWNhdGVzMTAwX211dGF0aW9uc19tdWx0aW5vbWlhbF9kYXRhXzIwMjQtMDEtMDUudHh0IiksIGhlYWRlciA9IFRSVUUsIHNlcCA9ICJcdCIpCgpjbl84XzFfV0dHR0dHRyA8LSByZWFkLmRlbGltKHBhc3RlMChyZXN1bHRzX2RpciwiYXBwbHlpbmdfcmlnaHRfYW5kX3dyb25nX2VxdWF0aW9ucy9yaWdodF92c193cm9uZ19lcXVhdGlvbnNfc3BlYXJtYW5fY29ycmVsYXRpb25fOCsxIFdHR0dHR0dfMTAwX3JlcGxpY2F0ZXMxMDBfbXV0YXRpb25zX211bHRpbm9taWFsX2RhdGFfMjAyNC0wMS0wNS50eHQiKSwgaGVhZGVyID0gVFJVRSwgc2VwID0gIlx0IikKY25fOF8xX0dXR0dHRyA8LSByZWFkLmRlbGltKHBhc3RlMChyZXN1bHRzX2RpciwiYXBwbHlpbmdfcmlnaHRfYW5kX3dyb25nX2VxdWF0aW9ucy9yaWdodF92c193cm9uZ19lcXVhdGlvbnNfc3BlYXJtYW5fY29ycmVsYXRpb25fOCsxIEdXR0dHR18xMDBfcmVwbGljYXRlczEwMF9tdXRhdGlvbnNfbXVsdGlub21pYWxfZGF0YV8yMDI0LTAxLTA1LnR4dCIpLCBoZWFkZXIgPSBUUlVFLCBzZXAgPSAiXHQiKQpjbl84XzFfR0dXR0cgPC0gcmVhZC5kZWxpbShwYXN0ZTAocmVzdWx0c19kaXIsImFwcGx5aW5nX3JpZ2h0X2FuZF93cm9uZ19lcXVhdGlvbnMvcmlnaHRfdnNfd3JvbmdfZXF1YXRpb25zX3NwZWFybWFuX2NvcnJlbGF0aW9uXzgrMSBHR1dHR18xMDBfcmVwbGljYXRlczEwMF9tdXRhdGlvbnNfbXVsdGlub21pYWxfZGF0YV8yMDI0LTAxLTA1LnR4dCIpLCBoZWFkZXIgPSBUUlVFLCBzZXAgPSAiXHQiKQpjbl84XzFfR0dHVyA8LSByZWFkLmRlbGltKHBhc3RlMChyZXN1bHRzX2RpciwiYXBwbHlpbmdfcmlnaHRfYW5kX3dyb25nX2VxdWF0aW9ucy9yaWdodF92c193cm9uZ19lcXVhdGlvbnNfc3BlYXJtYW5fY29ycmVsYXRpb25fOCsxIEdHR1dfMTAwX3JlcGxpY2F0ZXMxMDBfbXV0YXRpb25zX211bHRpbm9taWFsX2RhdGFfMjAyNC0wMS0wNS50eHQiKSwgaGVhZGVyID0gVFJVRSwgc2VwID0gIlx0IikKCmNuXzhfMl9XR0dHR0dHIDwtIHJlYWQuZGVsaW0ocGFzdGUwKHJlc3VsdHNfZGlyLCJhcHBseWluZ19yaWdodF9hbmRfd3JvbmdfZXF1YXRpb25zL3JpZ2h0X3ZzX3dyb25nX2VxdWF0aW9uc19zcGVhcm1hbl9jb3JyZWxhdGlvbl84KzIgV0dHR0dHR18xMDBfcmVwbGljYXRlczEwMF9tdXRhdGlvbnNfbXVsdGlub21pYWxfZGF0YV8yMDI0LTAxLTA1LnR4dCIpLCBoZWFkZXIgPSBUUlVFLCBzZXAgPSAiXHQiKQpjbl84XzJfR1dHR0dHIDwtIHJlYWQuZGVsaW0ocGFzdGUwKHJlc3VsdHNfZGlyLCJhcHBseWluZ19yaWdodF9hbmRfd3JvbmdfZXF1YXRpb25zL3JpZ2h0X3ZzX3dyb25nX2VxdWF0aW9uc19zcGVhcm1hbl9jb3JyZWxhdGlvbl84KzIgR1dHR0dHXzEwMF9yZXBsaWNhdGVzMTAwX211dGF0aW9uc19tdWx0aW5vbWlhbF9kYXRhXzIwMjQtMDEtMDUudHh0IiksIGhlYWRlciA9IFRSVUUsIHNlcCA9ICJcdCIpCmNuXzhfMl9HR1dHRyA8LSByZWFkLmRlbGltKHBhc3RlMChyZXN1bHRzX2RpciwiYXBwbHlpbmdfcmlnaHRfYW5kX3dyb25nX2VxdWF0aW9ucy9yaWdodF92c193cm9uZ19lcXVhdGlvbnNfc3BlYXJtYW5fY29ycmVsYXRpb25fOCsyIEdHV0dHXzEwMF9yZXBsaWNhdGVzMTAwX211dGF0aW9uc19tdWx0aW5vbWlhbF9kYXRhXzIwMjQtMDEtMDUudHh0IiksIGhlYWRlciA9IFRSVUUsIHNlcCA9ICJcdCIpCmNuXzhfMl9HR0dXIDwtIHJlYWQuZGVsaW0ocGFzdGUwKHJlc3VsdHNfZGlyLCJhcHBseWluZ19yaWdodF9hbmRfd3JvbmdfZXF1YXRpb25zL3JpZ2h0X3ZzX3dyb25nX2VxdWF0aW9uc19zcGVhcm1hbl9jb3JyZWxhdGlvbl84KzIgR0dHV18xMDBfcmVwbGljYXRlczEwMF9tdXRhdGlvbnNfbXVsdGlub21pYWxfZGF0YV8yMDI0LTAxLTA1LnR4dCIpLCBoZWFkZXIgPSBUUlVFLCBzZXAgPSAiXHQiKQpgYGAKYGBge3J9CmNuXzhfeCA8LSByYmluZChjbl84XzBfV0dHR0dHRywgY25fOF8wX0dXR0dHRywgY25fOF8wX0dHV0dHLCBjbl84XzBfR0dHVywKICAgICAgICAgICAgICAgIGNuXzhfMV9XR0dHR0dHLCBjbl84XzFfR1dHR0dHLCBjbl84XzFfR0dXR0csIGNuXzhfMV9HR0dXLAogICAgICAgICAgICAgICAgY25fOF8yX1dHR0dHR0csIGNuXzhfMl9HV0dHR0csIGNuXzhfMl9HR1dHRywgY25fOF8yX0dHR1cpCmBgYAoKYGBge3J9CmNuXzhfeCRTaWduaWZpY2FuY2UgPC0gaWZlbHNlKGNuXzhfeCRTcGVhcm1hbl9hZGp1c3RlZF9wIDwgMC4wNSwgIlNpZ25pZmljYW50IiwiTm90IFNpZ25pZmljYW50IikKYGBgCgoKYGBge3J9CmNuXzhfeF9wZWFyc29uX3Bsb3QgPC0gZ2dwbG90KGNuXzhfeCwgYWVzKHggPSBUcnVlX29yZGVyLCB5ID0gQXBwbGllZF9vcmRlciwgZmlsbCA9IFNwZWFybWFuX3JobykpKwogIGdlb21fdGlsZShhZXMoY29sb3I9YXMuZmFjdG9yKFNpZ25pZmljYW5jZSksIHdpZHRoPTAuOSwgaGVpZ2h0PTAuOSksIHNpemU9MC4zKSsKICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IGMoImZpcmVicmljayIsInJveWFsYmx1ZSIsImdyZXkiKSwgbGltaXRzID0gYygiU2lnbmlmaWNhbnQiLCJOb3QgU2lnbmlmaWNhbnQiLE5BKSwgbmFtZSA9ICJBZGp1c3RlZCBwIikrCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbD1yb3VuZChTcGVhcm1hbl9yaG8sZGlnaXRzID0gMikpLCBzaXplID0gMikrCiAgZmFjZXRfZ3JpZChyb3dzID0gdmFycyhUaW1lcG9pbnQpLCBjb2xzID0gdmFycyhDTl9zdGF0ZSkpKwogICMgc2NhbGVfZmlsbF9ncmFkaWVudG4oY29sb3JzID0gdmlyaWRpc19wYWwob3B0aW9uID0gIm1hZ21hIikoMTAwKSwgbGltaXRzPWMoLTEsIDEpLCAKICAjICAgICAgICAgICAgICAgICAgICAgIG5hLnZhbHVlID0gImdyZXkiKSsKICBzY2FsZV9maWxsX2Rpc3RpbGxlcihwYWxldHRlID0gIlJkQnUiLCBsaW1pdHMgPSBjKC0xLDEpLCBuYW1lID0gIlNwZWFybWFuIM+BIikrCiAgIyBzY2FsZV9maWxsX3ZpcmlkaXMob3B0aW9uID0gIm1hZ21hIikrCiAgdGhlbWVfbWluaW1hbCgpKwogIHlsYWIoIkFwcGxpZWQgdGltaW5nIG9yZGVyIikrCiAgeGxhYigiVHJ1ZSBzaW11bGF0ZWQgdGltaW5nIG9yZGVyIikKY25fOF94X3BlYXJzb25fcGxvdApgYGAKCiMjIDkreApSZWFkIGluIHNhbXBsZSBkYXRhLgpgYGB7cn0KY25fOV8wX1dHR0dHR0dHIDwtIHJlYWQuZGVsaW0ocGFzdGUwKHJlc3VsdHNfZGlyLCJhcHBseWluZ19yaWdodF9hbmRfd3JvbmdfZXF1YXRpb25zL3JpZ2h0X3ZzX3dyb25nX2VxdWF0aW9uc19zcGVhcm1hbl9jb3JyZWxhdGlvbl85KzAgV0dHR0dHR0dfMTAwX3JlcGxpY2F0ZXMxMDBfbXV0YXRpb25zX211bHRpbm9taWFsX2RhdGFfMjAyNC0wMS0wNS50eHQiKSwgaGVhZGVyID0gVFJVRSwgc2VwID0gIlx0IikKY25fOV8wX0dXR0dHR0cgPC0gcmVhZC5kZWxpbShwYXN0ZTAocmVzdWx0c19kaXIsImFwcGx5aW5nX3JpZ2h0X2FuZF93cm9uZ19lcXVhdGlvbnMvcmlnaHRfdnNfd3JvbmdfZXF1YXRpb25zX3NwZWFybWFuX2NvcnJlbGF0aW9uXzkrMCBHV0dHR0dHXzEwMF9yZXBsaWNhdGVzMTAwX211dGF0aW9uc19tdWx0aW5vbWlhbF9kYXRhXzIwMjQtMDEtMDUudHh0IiksIGhlYWRlciA9IFRSVUUsIHNlcCA9ICJcdCIpCmNuXzlfMF9HR1dHR0cgPC0gcmVhZC5kZWxpbShwYXN0ZTAocmVzdWx0c19kaXIsImFwcGx5aW5nX3JpZ2h0X2FuZF93cm9uZ19lcXVhdGlvbnMvcmlnaHRfdnNfd3JvbmdfZXF1YXRpb25zX3NwZWFybWFuX2NvcnJlbGF0aW9uXzkrMCBHR1dHR0dfMTAwX3JlcGxpY2F0ZXMxMDBfbXV0YXRpb25zX211bHRpbm9taWFsX2RhdGFfMjAyNC0wMS0wNS50eHQiKSwgaGVhZGVyID0gVFJVRSwgc2VwID0gIlx0IikKY25fOV8wX0dHR1dHIDwtIHJlYWQuZGVsaW0ocGFzdGUwKHJlc3VsdHNfZGlyLCJhcHBseWluZ19yaWdodF9hbmRfd3JvbmdfZXF1YXRpb25zL3JpZ2h0X3ZzX3dyb25nX2VxdWF0aW9uc19zcGVhcm1hbl9jb3JyZWxhdGlvbl85KzAgR0dHV0dfMTAwX3JlcGxpY2F0ZXMxMDBfbXV0YXRpb25zX211bHRpbm9taWFsX2RhdGFfMjAyNC0wMS0wNS50eHQiKSwgaGVhZGVyID0gVFJVRSwgc2VwID0gIlx0IikKCmNuXzlfMV9XR0dHR0dHRyA8LSByZWFkLmRlbGltKHBhc3RlMChyZXN1bHRzX2RpciwiYXBwbHlpbmdfcmlnaHRfYW5kX3dyb25nX2VxdWF0aW9ucy9yaWdodF92c193cm9uZ19lcXVhdGlvbnNfc3BlYXJtYW5fY29ycmVsYXRpb25fOSsxIFdHR0dHR0dHXzEwMF9yZXBsaWNhdGVzMTAwX211dGF0aW9uc19tdWx0aW5vbWlhbF9kYXRhXzIwMjQtMDEtMDUudHh0IiksIGhlYWRlciA9IFRSVUUsIHNlcCA9ICJcdCIpCmNuXzlfMV9HV0dHR0dHIDwtIHJlYWQuZGVsaW0ocGFzdGUwKHJlc3VsdHNfZGlyLCJhcHBseWluZ19yaWdodF9hbmRfd3JvbmdfZXF1YXRpb25zL3JpZ2h0X3ZzX3dyb25nX2VxdWF0aW9uc19zcGVhcm1hbl9jb3JyZWxhdGlvbl85KzEgR1dHR0dHR18xMDBfcmVwbGljYXRlczEwMF9tdXRhdGlvbnNfbXVsdGlub21pYWxfZGF0YV8yMDI0LTAxLTA1LnR4dCIpLCBoZWFkZXIgPSBUUlVFLCBzZXAgPSAiXHQiKQpjbl85XzFfR0dXR0dHIDwtIHJlYWQuZGVsaW0ocGFzdGUwKHJlc3VsdHNfZGlyLCJhcHBseWluZ19yaWdodF9hbmRfd3JvbmdfZXF1YXRpb25zL3JpZ2h0X3ZzX3dyb25nX2VxdWF0aW9uc19zcGVhcm1hbl9jb3JyZWxhdGlvbl85KzEgR0dXR0dHXzEwMF9yZXBsaWNhdGVzMTAwX211dGF0aW9uc19tdWx0aW5vbWlhbF9kYXRhXzIwMjQtMDEtMDUudHh0IiksIGhlYWRlciA9IFRSVUUsIHNlcCA9ICJcdCIpCmNuXzlfMV9HR0dXRyA8LSByZWFkLmRlbGltKHBhc3RlMChyZXN1bHRzX2RpciwiYXBwbHlpbmdfcmlnaHRfYW5kX3dyb25nX2VxdWF0aW9ucy9yaWdodF92c193cm9uZ19lcXVhdGlvbnNfc3BlYXJtYW5fY29ycmVsYXRpb25fOSsxIEdHR1dHXzEwMF9yZXBsaWNhdGVzMTAwX211dGF0aW9uc19tdWx0aW5vbWlhbF9kYXRhXzIwMjQtMDEtMDUudHh0IiksIGhlYWRlciA9IFRSVUUsIHNlcCA9ICJcdCIpCgpjbl85XzJfV0dHR0dHR0cgPC0gcmVhZC5kZWxpbShwYXN0ZTAocmVzdWx0c19kaXIsImFwcGx5aW5nX3JpZ2h0X2FuZF93cm9uZ19lcXVhdGlvbnMvcmlnaHRfdnNfd3JvbmdfZXF1YXRpb25zX3NwZWFybWFuX2NvcnJlbGF0aW9uXzkrMiBXR0dHR0dHR18xMDBfcmVwbGljYXRlczEwMF9tdXRhdGlvbnNfbXVsdGlub21pYWxfZGF0YV8yMDI0LTAxLTA1LnR4dCIpLCBoZWFkZXIgPSBUUlVFLCBzZXAgPSAiXHQiKQpjbl85XzJfR1dHR0dHRyA8LSByZWFkLmRlbGltKHBhc3RlMChyZXN1bHRzX2RpciwiYXBwbHlpbmdfcmlnaHRfYW5kX3dyb25nX2VxdWF0aW9ucy9yaWdodF92c193cm9uZ19lcXVhdGlvbnNfc3BlYXJtYW5fY29ycmVsYXRpb25fOSsyIEdXR0dHR0dfMTAwX3JlcGxpY2F0ZXMxMDBfbXV0YXRpb25zX211bHRpbm9taWFsX2RhdGFfMjAyNC0wMS0wNS50eHQiKSwgaGVhZGVyID0gVFJVRSwgc2VwID0gIlx0IikKY25fOV8yX0dHV0dHRyA8LSByZWFkLmRlbGltKHBhc3RlMChyZXN1bHRzX2RpciwiYXBwbHlpbmdfcmlnaHRfYW5kX3dyb25nX2VxdWF0aW9ucy9yaWdodF92c193cm9uZ19lcXVhdGlvbnNfc3BlYXJtYW5fY29ycmVsYXRpb25fOSsyIEdHV0dHR18xMDBfcmVwbGljYXRlczEwMF9tdXRhdGlvbnNfbXVsdGlub21pYWxfZGF0YV8yMDI0LTAxLTA1LnR4dCIpLCBoZWFkZXIgPSBUUlVFLCBzZXAgPSAiXHQiKQpjbl85XzJfR0dHV0cgPC0gcmVhZC5kZWxpbShwYXN0ZTAocmVzdWx0c19kaXIsImFwcGx5aW5nX3JpZ2h0X2FuZF93cm9uZ19lcXVhdGlvbnMvcmlnaHRfdnNfd3JvbmdfZXF1YXRpb25zX3NwZWFybWFuX2NvcnJlbGF0aW9uXzkrMiBHR0dXR18xMDBfcmVwbGljYXRlczEwMF9tdXRhdGlvbnNfbXVsdGlub21pYWxfZGF0YV8yMDI0LTAxLTA1LnR4dCIpLCBoZWFkZXIgPSBUUlVFLCBzZXAgPSAiXHQiKQpgYGAKYGBge3J9CmNuXzlfeCA8LSByYmluZChjbl85XzBfV0dHR0dHR0csIGNuXzlfMF9HV0dHR0dHLCBjbl85XzBfR0dXR0dHLCBjbl85XzBfR0dHV0csCiAgICAgICAgICAgICAgICBjbl85XzFfV0dHR0dHR0csIGNuXzlfMV9HV0dHR0dHLCBjbl85XzFfR0dXR0dHLCBjbl85XzFfR0dHV0csCiAgICAgICAgICAgICAgICBjbl85XzJfV0dHR0dHR0csIGNuXzlfMl9HV0dHR0dHLCBjbl85XzJfR0dXR0dHLCBjbl85XzJfR0dHV0cpCmBgYAoKYGBge3J9CmNuXzlfeCRTaWduaWZpY2FuY2UgPC0gaWZlbHNlKGNuXzlfeCRTcGVhcm1hbl9hZGp1c3RlZF9wIDwgMC4wNSwgIlNpZ25pZmljYW50IiwiTm90IFNpZ25pZmljYW50IikKYGBgCgoKYGBge3J9CmNuXzlfeF9wZWFyc29uX3Bsb3QgPC0gZ2dwbG90KGNuXzlfeCwgYWVzKHggPSBUcnVlX29yZGVyLCB5ID0gQXBwbGllZF9vcmRlciwgZmlsbCA9IFNwZWFybWFuX3JobykpKwogIGdlb21fdGlsZShhZXMoY29sb3I9YXMuZmFjdG9yKFNpZ25pZmljYW5jZSksIHdpZHRoPTAuOSwgaGVpZ2h0PTAuOSksIHNpemU9MC4zKSsKICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IGMoImZpcmVicmljayIsInJveWFsYmx1ZSIsImdyZXkiKSwgbGltaXRzID0gYygiU2lnbmlmaWNhbnQiLCJOb3QgU2lnbmlmaWNhbnQiLE5BKSwgbmFtZSA9ICJBZGp1c3RlZCBwIikrCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbD1yb3VuZChTcGVhcm1hbl9yaG8sZGlnaXRzID0gMikpLCBzaXplID0gMikrCiAgZmFjZXRfZ3JpZChyb3dzID0gdmFycyhUaW1lcG9pbnQpLCBjb2xzID0gdmFycyhDTl9zdGF0ZSkpKwogICMgc2NhbGVfZmlsbF9ncmFkaWVudG4oY29sb3JzID0gdmlyaWRpc19wYWwob3B0aW9uID0gIm1hZ21hIikoMTAwKSwgbGltaXRzPWMoLTEsIDEpLCAKICAjICAgICAgICAgICAgICAgICAgICAgIG5hLnZhbHVlID0gImdyZXkiKSsKICBzY2FsZV9maWxsX2Rpc3RpbGxlcihwYWxldHRlID0gIlJkQnUiLCBsaW1pdHMgPSBjKC0xLDEpLCBuYW1lID0gIlNwZWFybWFuIM+BIikrCiAgIyBzY2FsZV9maWxsX3ZpcmlkaXMob3B0aW9uID0gIm1hZ21hIikrCiAgdGhlbWVfbWluaW1hbCgpKwogIHlsYWIoIkFwcGxpZWQgdGltaW5nIG9yZGVyIikrCiAgeGxhYigiVHJ1ZSBzaW11bGF0ZWQgdGltaW5nIG9yZGVyIikKY25fOV94X3BlYXJzb25fcGxvdApgYGAKCiMjIDEwK3gKUmVhZCBpbiBzYW1wbGUgZGF0YS4KYGBge3J9CmNuXzEwXzBfV0dHR0dHR0dHIDwtIHJlYWQuZGVsaW0ocGFzdGUwKHJlc3VsdHNfZGlyLCJhcHBseWluZ19yaWdodF9hbmRfd3JvbmdfZXF1YXRpb25zL3JpZ2h0X3ZzX3dyb25nX2VxdWF0aW9uc19zcGVhcm1hbl9jb3JyZWxhdGlvbl8xMCswIFdHR0dHR0dHR18xMDBfcmVwbGljYXRlczEwMF9tdXRhdGlvbnNfbXVsdGlub21pYWxfZGF0YV8yMDI0LTAxLTA1LnR4dCIpLCBoZWFkZXIgPSBUUlVFLCBzZXAgPSAiXHQiKQpjbl8xMF8wX0dXR0dHR0dHIDwtIHJlYWQuZGVsaW0ocGFzdGUwKHJlc3VsdHNfZGlyLCJhcHBseWluZ19yaWdodF9hbmRfd3JvbmdfZXF1YXRpb25zL3JpZ2h0X3ZzX3dyb25nX2VxdWF0aW9uc19zcGVhcm1hbl9jb3JyZWxhdGlvbl8xMCswIEdXR0dHR0dHXzEwMF9yZXBsaWNhdGVzMTAwX211dGF0aW9uc19tdWx0aW5vbWlhbF9kYXRhXzIwMjQtMDEtMDUudHh0IiksIGhlYWRlciA9IFRSVUUsIHNlcCA9ICJcdCIpCmNuXzEwXzBfR0dXR0dHRyA8LSByZWFkLmRlbGltKHBhc3RlMChyZXN1bHRzX2RpciwiYXBwbHlpbmdfcmlnaHRfYW5kX3dyb25nX2VxdWF0aW9ucy9yaWdodF92c193cm9uZ19lcXVhdGlvbnNfc3BlYXJtYW5fY29ycmVsYXRpb25fMTArMCBHR1dHR0dHXzEwMF9yZXBsaWNhdGVzMTAwX211dGF0aW9uc19tdWx0aW5vbWlhbF9kYXRhXzIwMjQtMDEtMDUudHh0IiksIGhlYWRlciA9IFRSVUUsIHNlcCA9ICJcdCIpCmNuXzEwXzBfR0dHV0dHIDwtIHJlYWQuZGVsaW0ocGFzdGUwKHJlc3VsdHNfZGlyLCJhcHBseWluZ19yaWdodF9hbmRfd3JvbmdfZXF1YXRpb25zL3JpZ2h0X3ZzX3dyb25nX2VxdWF0aW9uc19zcGVhcm1hbl9jb3JyZWxhdGlvbl8xMCswIEdHR1dHR18xMDBfcmVwbGljYXRlczEwMF9tdXRhdGlvbnNfbXVsdGlub21pYWxfZGF0YV8yMDI0LTAxLTA1LnR4dCIpLCBoZWFkZXIgPSBUUlVFLCBzZXAgPSAiXHQiKQpjbl8xMF8wX0dHR0dXIDwtIHJlYWQuZGVsaW0ocGFzdGUwKHJlc3VsdHNfZGlyLCJhcHBseWluZ19yaWdodF9hbmRfd3JvbmdfZXF1YXRpb25zL3JpZ2h0X3ZzX3dyb25nX2VxdWF0aW9uc19zcGVhcm1hbl9jb3JyZWxhdGlvbl8xMCswIEdHR0dXXzEwMF9yZXBsaWNhdGVzMTAwX211dGF0aW9uc19tdWx0aW5vbWlhbF9kYXRhXzIwMjQtMDEtMDUudHh0IiksIGhlYWRlciA9IFRSVUUsIHNlcCA9ICJcdCIpCgpjbl8xMF8xX1dHR0dHR0dHRyA8LSByZWFkLmRlbGltKHBhc3RlMChyZXN1bHRzX2RpciwiYXBwbHlpbmdfcmlnaHRfYW5kX3dyb25nX2VxdWF0aW9ucy9yaWdodF92c193cm9uZ19lcXVhdGlvbnNfc3BlYXJtYW5fY29ycmVsYXRpb25fMTArMSBXR0dHR0dHR0dfMTAwX3JlcGxpY2F0ZXMxMDBfbXV0YXRpb25zX211bHRpbm9taWFsX2RhdGFfMjAyNC0wMS0wNS50eHQiKSwgaGVhZGVyID0gVFJVRSwgc2VwID0gIlx0IikKY25fMTBfMV9HV0dHR0dHRyA8LSByZWFkLmRlbGltKHBhc3RlMChyZXN1bHRzX2RpciwiYXBwbHlpbmdfcmlnaHRfYW5kX3dyb25nX2VxdWF0aW9ucy9yaWdodF92c193cm9uZ19lcXVhdGlvbnNfc3BlYXJtYW5fY29ycmVsYXRpb25fMTArMSBHV0dHR0dHR18xMDBfcmVwbGljYXRlczEwMF9tdXRhdGlvbnNfbXVsdGlub21pYWxfZGF0YV8yMDI0LTAxLTA1LnR4dCIpLCBoZWFkZXIgPSBUUlVFLCBzZXAgPSAiXHQiKQpjbl8xMF8xX0dHV0dHR0cgPC0gcmVhZC5kZWxpbShwYXN0ZTAocmVzdWx0c19kaXIsImFwcGx5aW5nX3JpZ2h0X2FuZF93cm9uZ19lcXVhdGlvbnMvcmlnaHRfdnNfd3JvbmdfZXF1YXRpb25zX3NwZWFybWFuX2NvcnJlbGF0aW9uXzEwKzEgR0dXR0dHR18xMDBfcmVwbGljYXRlczEwMF9tdXRhdGlvbnNfbXVsdGlub21pYWxfZGF0YV8yMDI0LTAxLTA1LnR4dCIpLCBoZWFkZXIgPSBUUlVFLCBzZXAgPSAiXHQiKQpjbl8xMF8xX0dHR1dHRyA8LSByZWFkLmRlbGltKHBhc3RlMChyZXN1bHRzX2RpciwiYXBwbHlpbmdfcmlnaHRfYW5kX3dyb25nX2VxdWF0aW9ucy9yaWdodF92c193cm9uZ19lcXVhdGlvbnNfc3BlYXJtYW5fY29ycmVsYXRpb25fMTArMSBHR0dXR0dfMTAwX3JlcGxpY2F0ZXMxMDBfbXV0YXRpb25zX211bHRpbm9taWFsX2RhdGFfMjAyNC0wMS0wNS50eHQiKSwgaGVhZGVyID0gVFJVRSwgc2VwID0gIlx0IikKY25fMTBfMV9HR0dHVyA8LSByZWFkLmRlbGltKHBhc3RlMChyZXN1bHRzX2RpciwiYXBwbHlpbmdfcmlnaHRfYW5kX3dyb25nX2VxdWF0aW9ucy9yaWdodF92c193cm9uZ19lcXVhdGlvbnNfc3BlYXJtYW5fY29ycmVsYXRpb25fMTArMSBHR0dHV18xMDBfcmVwbGljYXRlczEwMF9tdXRhdGlvbnNfbXVsdGlub21pYWxfZGF0YV8yMDI0LTAxLTA1LnR4dCIpLCBoZWFkZXIgPSBUUlVFLCBzZXAgPSAiXHQiKQoKY25fMTBfMl9XR0dHR0dHR0cgPC0gcmVhZC5kZWxpbShwYXN0ZTAocmVzdWx0c19kaXIsImFwcGx5aW5nX3JpZ2h0X2FuZF93cm9uZ19lcXVhdGlvbnMvcmlnaHRfdnNfd3JvbmdfZXF1YXRpb25zX3NwZWFybWFuX2NvcnJlbGF0aW9uXzEwKzIgV0dHR0dHR0dHXzEwMF9yZXBsaWNhdGVzMTAwX211dGF0aW9uc19tdWx0aW5vbWlhbF9kYXRhXzIwMjQtMDEtMDUudHh0IiksIGhlYWRlciA9IFRSVUUsIHNlcCA9ICJcdCIpCmNuXzEwXzJfR1dHR0dHR0cgPC0gcmVhZC5kZWxpbShwYXN0ZTAocmVzdWx0c19kaXIsImFwcGx5aW5nX3JpZ2h0X2FuZF93cm9uZ19lcXVhdGlvbnMvcmlnaHRfdnNfd3JvbmdfZXF1YXRpb25zX3NwZWFybWFuX2NvcnJlbGF0aW9uXzEwKzIgR1dHR0dHR0dfMTAwX3JlcGxpY2F0ZXMxMDBfbXV0YXRpb25zX211bHRpbm9taWFsX2RhdGFfMjAyNC0wMS0wNS50eHQiKSwgaGVhZGVyID0gVFJVRSwgc2VwID0gIlx0IikKY25fMTBfMl9HR1dHR0dHIDwtIHJlYWQuZGVsaW0ocGFzdGUwKHJlc3VsdHNfZGlyLCJhcHBseWluZ19yaWdodF9hbmRfd3JvbmdfZXF1YXRpb25zL3JpZ2h0X3ZzX3dyb25nX2VxdWF0aW9uc19zcGVhcm1hbl9jb3JyZWxhdGlvbl8xMCsyIEdHV0dHR0dfMTAwX3JlcGxpY2F0ZXMxMDBfbXV0YXRpb25zX211bHRpbm9taWFsX2RhdGFfMjAyNC0wMS0wNS50eHQiKSwgaGVhZGVyID0gVFJVRSwgc2VwID0gIlx0IikKY25fMTBfMl9HR0dXR0cgPC0gcmVhZC5kZWxpbShwYXN0ZTAocmVzdWx0c19kaXIsImFwcGx5aW5nX3JpZ2h0X2FuZF93cm9uZ19lcXVhdGlvbnMvcmlnaHRfdnNfd3JvbmdfZXF1YXRpb25zX3NwZWFybWFuX2NvcnJlbGF0aW9uXzEwKzIgR0dHV0dHXzEwMF9yZXBsaWNhdGVzMTAwX211dGF0aW9uc19tdWx0aW5vbWlhbF9kYXRhXzIwMjQtMDEtMDUudHh0IiksIGhlYWRlciA9IFRSVUUsIHNlcCA9ICJcdCIpCmNuXzEwXzJfR0dHR1cgPC0gcmVhZC5kZWxpbShwYXN0ZTAocmVzdWx0c19kaXIsImFwcGx5aW5nX3JpZ2h0X2FuZF93cm9uZ19lcXVhdGlvbnMvcmlnaHRfdnNfd3JvbmdfZXF1YXRpb25zX3NwZWFybWFuX2NvcnJlbGF0aW9uXzEwKzIgR0dHR1dfMTAwX3JlcGxpY2F0ZXMxMDBfbXV0YXRpb25zX211bHRpbm9taWFsX2RhdGFfMjAyNC0wMS0wNS50eHQiKSwgaGVhZGVyID0gVFJVRSwgc2VwID0gIlx0IikKYGBgCmBgYHtyfQpjbl8xMF94IDwtIHJiaW5kKGNuXzEwXzBfV0dHR0dHR0dHLCBjbl8xMF8wX0dXR0dHR0dHLCBjbl8xMF8wX0dHV0dHR0csIGNuXzEwXzBfR0dHV0dHLCBjbl8xMF8wX0dHR0dXLAogICAgICAgICAgICAgICAgIGNuXzEwXzFfV0dHR0dHR0dHLCBjbl8xMF8xX0dXR0dHR0dHLCBjbl8xMF8xX0dHV0dHR0csIGNuXzEwXzFfR0dHV0dHLCBjbl8xMF8xX0dHR0dXLAogICAgICAgICAgICAgICAgIGNuXzEwXzJfV0dHR0dHR0dHLCBjbl8xMF8yX0dXR0dHR0dHLCBjbl8xMF8yX0dHV0dHR0csIGNuXzEwXzJfR0dHV0dHLCBjbl8xMF8yX0dHR0dXKQpgYGAKCmBgYHtyfQpjbl8xMF94JFNpZ25pZmljYW5jZSA8LSBpZmVsc2UoY25fMTBfeCRTcGVhcm1hbl9hZGp1c3RlZF9wIDwgMC4wNSwgIlNpZ25pZmljYW50IiwiTm90IFNpZ25pZmljYW50IikKYGBgCgoKYGBge3J9CmNuXzEwX3hfcGVhcnNvbl9wbG90IDwtIGdncGxvdChjbl8xMF94LCBhZXMoeCA9IFRydWVfb3JkZXIsIHkgPSBBcHBsaWVkX29yZGVyLCBmaWxsID0gU3BlYXJtYW5fcmhvKSkrCiAgZ2VvbV90aWxlKGFlcyhjb2xvcj1hcy5mYWN0b3IoU2lnbmlmaWNhbmNlKSwgd2lkdGg9MC45LCBoZWlnaHQ9MC45KSwgc2l6ZT0wLjMpKwogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gYygiZmlyZWJyaWNrIiwicm95YWxibHVlIiwiZ3JleSIpLCBsaW1pdHMgPSBjKCJTaWduaWZpY2FudCIsIk5vdCBTaWduaWZpY2FudCIsTkEpLCBuYW1lID0gIkFkanVzdGVkIHAiKSsKICBnZW9tX3RleHQoYWVzKGxhYmVsPXJvdW5kKFNwZWFybWFuX3JobyxkaWdpdHMgPSAyKSksIHNpemUgPSAyKSsKICBmYWNldF9ncmlkKHJvd3MgPSB2YXJzKFRpbWVwb2ludCksIGNvbHMgPSB2YXJzKENOX3N0YXRlKSkrCiAgIyBzY2FsZV9maWxsX2dyYWRpZW50bihjb2xvcnMgPSB2aXJpZGlzX3BhbChvcHRpb24gPSAibWFnbWEiKSgxMDApLCBsaW1pdHM9YygtMSwgMSksIAogICMgICAgICAgICAgICAgICAgICAgICAgbmEudmFsdWUgPSAiZ3JleSIpKwogIHNjYWxlX2ZpbGxfZGlzdGlsbGVyKHBhbGV0dGUgPSAiUmRCdSIsIGxpbWl0cyA9IGMoLTEsMSksIG5hbWUgPSAiU3BlYXJtYW4gz4EiKSsKICAjIHNjYWxlX2ZpbGxfdmlyaWRpcyhvcHRpb24gPSAibWFnbWEiKSsKICB0aGVtZV9taW5pbWFsKCkrCiAgeWxhYigiQXBwbGllZCB0aW1pbmcgb3JkZXIiKSsKICB4bGFiKCJUcnVlIHNpbXVsYXRlZCB0aW1pbmcgb3JkZXIiKQpjbl8xMF94X3BlYXJzb25fcGxvdApgYGAKCiMjIENvbWJpbmVkIHBsb3QKYGBge3IgZmlnLmhlaWdodD0yMi41LCBmaWcud2lkdGg9MTcuOH0KcG5nKHBhc3RlMChvdXRkaXIsInBlYXJzb25fYW5kX21peF9tYXRjaF9lcXVhdGlvbnNfNF85XyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuX3JlcGxpY2F0ZXNfbWlzbWF0Y2hlZCwiX3JlcGxpY2F0ZXMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbl9tdXRhdGlvbnNfbWlzbWF0Y2hlZCwiX211dGF0aW9ucyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiXyIsIm11bHRpbm9taWFsX2RhdGEiLCJfIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN5cy5EYXRlKCksIi5wbmciKSwKICAgIGhlaWdodCA9IGZpZ3VyZV9oZWlnaHQsIHdpZHRoID0gZmlndXJlX3dpZHRoLCB1bml0cyA9ICJjbSIsCiAgICByZXMgPSAzNTApCgpncmlkLmFycmFuZ2UoY25fNF94X3BlYXJzb25fcGxvdCt0aGVtZShheGlzLnRpdGxlID0gZWxlbWVudF9ibGFuaygpLGF4aXMudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gNiksIHBsb3QubWFyZ2luID0gdW5pdChjKDAsMCwwLDAuMiksICJjbSIpLCBsZWdlbmQucG9zaXRpb24gPSAibGVmdCIsIHN0cmlwLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgpLCBsZWdlbmQuYm94LnNwYWNpbmcgPSB1bml0KDAuMDUsICJjbSIpLCBsZWdlbmQua2V5LndpZHRoID0gdW5pdCgwLjMsImNtIiksIGxlZ2VuZC50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSA2KSwgbGVnZW5kLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSA2KSwgbGVnZW5kLmJveCA9ICJob3Jpem9udGFsIiwgbGVnZW5kLnNwYWNpbmcgPSB1bml0KDAsImNtIikpLCAKICAgICAgICAgICAgIGNuXzVfeF9wZWFyc29uX3Bsb3QrdGhlbWUoYXhpcy50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSxheGlzLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDYpLCBwbG90Lm1hcmdpbiA9IHVuaXQoYygwLDAsMCwwKSwgImNtIiksIGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiwgc3RyaXAudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gOCkpLAogICAgICAgICAgICAgY25fNl94X3BlYXJzb25fcGxvdCt0aGVtZShheGlzLnRpdGxlID0gZWxlbWVudF9ibGFuaygpLGF4aXMudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gNiksIHBsb3QubWFyZ2luID0gdW5pdChjKDAsMCwwLDApLCAiY20iKSwgbGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLCBzdHJpcC50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSA4KSwgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSAtMjApKSwgCiAgICAgICAgICAgICBjbl83X3hfcGVhcnNvbl9wbG90K3RoZW1lKGF4aXMudGl0bGUgPSBlbGVtZW50X2JsYW5rKCksYXhpcy50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSA2KSwgcGxvdC5tYXJnaW4gPSB1bml0KGMoMCwwLDAsMCksICJjbSIpLCBsZWdlbmQucG9zaXRpb24gPSAibm9uZSIsIHN0cmlwLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgpLCBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IC0yMCkpLAogICAgICAgICAgICAgY25fOF94X3BlYXJzb25fcGxvdCt0aGVtZShheGlzLnRpdGxlID0gZWxlbWVudF9ibGFuaygpLGF4aXMudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gNiksIHBsb3QubWFyZ2luID0gdW5pdChjKDAsMCwwLDApLCAiY20iKSwgbGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLCBzdHJpcC50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSA4KSwgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSAtMjUpKSwgCiAgICAgICAgICAgICBjbl85X3hfcGVhcnNvbl9wbG90K3RoZW1lKGF4aXMudGl0bGUgPSBlbGVtZW50X2JsYW5rKCksYXhpcy50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSA2KSwgcGxvdC5tYXJnaW4gPSB1bml0KGMoMCwwLDAsMCksICJjbSIpLCBsZWdlbmQucG9zaXRpb24gPSAibm9uZSIsIHN0cmlwLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgpLCBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IC0yNSkpLAogICAgICAgICAgICAgIyBjbl8xMF94X3BlYXJzb25fcGxvdCt0aGVtZShheGlzLnRpdGxlID0gZWxlbWVudF9ibGFuaygpLGF4aXMudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gNCksIHBsb3QubWFyZ2luID0gdW5pdChjKDAsMCwwLDApLCAiY20iKSksCiAgICAgICAgICAgICBuY29sID0gMiwgbnJvdyA9IDMsCiAgICAgICAgICAgICBsZWZ0ID0gIkFwcGxpZWQgdGltaW5nIG9yZGVyIiwgYm90dG9tID0gIlRydWUgc2ltdWxhdGVkIHRpbWluZyBvcmRlciIsCiAgICAgICAgICAgICBsYXlvdXRfbWF0cml4ID0gcmJpbmQoYygxLDIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMoMyw0KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjKDUsNikKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIGMoNyw3KQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICksCiAgICAgICAgICAgICBoZWlnaHRzID0gYygzLDUsOSksIHBhZGRpbmcgPSB1bml0KDAuNSwgImNtIikpCgpncmlkLnRleHQoIkEiLCB4PTAuMDUsIHk9MC45OCwgZ3A9Z3Bhcihmb250c2l6ZT0xNikpCmdyaWQudGV4dCgiQiIsIHg9MC41MCwgeT0wLjk4LCBncD1ncGFyKGZvbnRzaXplPTE2KSkKZ3JpZC50ZXh0KCJDIiwgeD0wLjA1LCB5PTAuODIsIGdwPWdwYXIoZm9udHNpemU9MTYpKQpncmlkLnRleHQoIkQiLCB4PTAuNTAsIHk9MC44MiwgZ3A9Z3Bhcihmb250c2l6ZT0xNikpCmdyaWQudGV4dCgiRSIsIHg9MC4wNSwgeT0wLjU0LCBncD1ncGFyKGZvbnRzaXplPTE2KSkKZ3JpZC50ZXh0KCJGIiwgeD0wLjUwLCB5PTAuNTQsIGdwPWdwYXIoZm9udHNpemU9MTYpKQoKZGV2Lm9mZigpCmBgYAoKYGBge3J9CnBuZyhwYXN0ZTAob3V0ZGlyLCJwZWFyc29uX2FuZF9taXhfbWF0Y2hfZXF1YXRpb25zXzEwX1hfIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5fcmVwbGljYXRlc19taXNtYXRjaGVkLCJfcmVwbGljYXRlcyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuX211dGF0aW9uc19taXNtYXRjaGVkLCJfbXV0YXRpb25zIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJfIiwibXVsdGlub21pYWxfZGF0YSIsIl8iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3lzLkRhdGUoKSwiLnBuZyIpLAogICAgaGVpZ2h0ID0gMTYsIHdpZHRoID0gZmlndXJlX3dpZHRoLCB1bml0cyA9ICJjbSIsCiAgICByZXMgPSAzNTApCmNuXzEwX3hfcGVhcnNvbl9wbG90KwogIHRoZW1lKGF4aXMudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gOCksIAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gLTIwLCBoanVzdCA9IC0wLjAxKSkKZGV2Lm9mZigpCmBgYAoKIyBTZXNzaW9uIGluZm8KYGBge3J9CnNlc3Npb25JbmZvKCkKYGBgCgpTYXZlIHNlc3Npb24gaW5mbwpgYGB7cn0Kd3JpdGVMaW5lcyhjYXB0dXJlLm91dHB1dChzZXNzaW9uSW5mbygpKSwgcGFzdGUwKG91dGRpcixkYXRhX3R5cGUsIl9wbG90dGluZ19zaW11bGF0aW9uX3Nlc3Npb25JbmZvXyIsU3lzLkRhdGUoKSwiLnR4dCIpKQpgYGAKCg==